题目链接:http://poj.org/problem?id=2001
//Accepted 564K 32MS C++ 1187B
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct TrieNode //c++里的struct 可以有函数的
{
int nCount; //记录有多少个分支经过该节点
struct TrieNode *next[26]; //题目中只有小写字母,所以是26,若有大小写则为52。若还有数字,自己用脚趾头想吧
TrieNode() //构造函数,就是在你申请一个节点空间时,把节点初始化
{
nCount = 0;
memset(next,0,sizeof(next));
}
};
char str[1010][30]; //看题目数据
TrieNode *root = NULL; //全局变量 ,尽管祝建华不建议多用,但在acm中,能方便就方便
void MakeTrie(char *s) //构造字典树
{
TrieNode * p = root;
TrieNode * tmp = NULL ;
for(size_t i = 0; i < strlen(s); i++)
{
if(p->next[ s[i] - 'a'] == NULL) //相当于一棵有26个儿子的树,当然你用到那个分支,就选那个s[i]-'a'就是这么来的
{
tmp = new TrieNode; //申请空间,初始化26个分支(memset啊啊啊),nCount置为0
p->next[ s[i] - 'a'] = tmp; //加到树上 看不懂,就去死吧
}
p = p->next[ s[i] - 'a']; //就像你写p = p->next一样
p->nCount ++; //记录有多少分支经过该节点
}
}
void SearchTrie(char *s)
{
TrieNode * p = root;
for(size_t i = 0; i < strlen(s); i++)
{
p = p->next[s[i] - 'a'];
printf("%c",s[i]);
if(p->nCount == 1) //==1就说明该节点只有1个分支经过,就说明以它为结尾的前缀是惟一的,果断跳出
break;
}
}
int main()
{
int num = 0;
root = new TrieNode;//自动调用构造函数初始化next[i]为NULL
while(cin >> str[num])
{
MakeTrie(str[num]);
num ++;
}
for(int i = 0; i < num; i++)
{
printf("%s ",str[i]);
SearchTrie(str[i]);
printf("\n");
}
return 0;
}