poj 2001 Shortest Prefixes (字符串_字典树)

题目链接:http://poj.org/problem?id=2001


题目大意:给定n个字符串,问每个字符串的最短表示。用这个最短表示就可以把其他字符串区别开来,比如abc和ab,前一个最短表示仍然是abc,后一个任然是ab,如果一个是abcde,一个是abce,那前面一个是abcd,后面一个i是abce。


解题思路:本题可用字段树解。最短表示有两种情况:一种是整个串是其他串的子串,那它的最短表示就是它自己。一种是这个串和其他串有公共前缀,那只要找最长的公共前缀加下一个不一样的字符就可以了。思路很简单,字典树写起来也不复杂。


测试数据:

carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate


abb
abb
abcd
ab


代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MIN 30
#define MAX 1100


struct node{

	int count;
	node *next[MIN];
}*root;
char str[MAX][MIN];


node *CreateNode()
{
	node *p;
	p = (node *) malloc (sizeof(node));
	p->count = 1;
	for (int i = 0; i < 26; ++i)
		p->next[i] = NULL;
	return p;
}
void release(node *p){

	for (int i = 0; i < 26; ++i)
		if (p->next[i] != NULL) release(p->next[i]);
	free(p);
}


void insert(char *str){

	int i = 0,k;
	node *p = root;


	while (str[i]) {

		k = str[i++] - 'a';
		if (p->next[k] == NULL)
			p->next[k] = CreateNode();
		else p->next[k]->count++;
		p = p->next[k];
	}
}
void search(char *str){

	int i = 0,k,j,flag = 0;
	node *p = root;


	while (str[i] && !flag) {
		
		k = str[i++] - 'a';
		p = p->next[k];
		if (p->count == 1) {

			flag = 1;
			printf("%s ",str);
			for (j = 0; j < i; ++j)
				printf("%c",str[j]);
			printf("\n");
		}
	}


	if (flag == 0)
		printf("%s %s\n",str,str);
}

int main()
{
	int i = 0,j,k;


	root = CreateNode();
	for (i = 0; scanf("%s",str[i]) != EOF; ++i)
		insert(str[i]);
	for (j = 0; j < i; ++j)
		search(str[j]);
	release(root);
}

本文章ZeroClock原创,但可以转载,因为我们是兄弟。

你可能感兴趣的:(c,struct,测试,null,search,insert)