前缀树的简单应用,
我的思路是每次加入单词是,为每个节点记录一个value,该value代表经过该节点的单词数目,每次取最短前缀时,只需要沿着单词查找第一个value值为1的节点,即表示只有该单词经过该节点。
C++写的代码,有点啰嗦..
0MS AC
#include <iostream>
#include <string>
using namespace std;
#define max_words 1100 //开始取的是1010,出现了runtime error
#define max_nodes (max_words*20)
#define characters 27
class Trie{
public:
Trie(){ sz = 1;memset(ch[0],0,sizeof(ch[0]));memset(val,0,sizeof(val));}
void insert(string s){
int u = 0, n = s.length();
for(int i = 0; i < n; i++){
int c = s[i] - 'a';
if(!ch[u][c]){ //没有出现过
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]++;
ch[u][c] = sz++;
}
else //出现过,该节点的value值加一
val[ch[u][c]]++;
u = ch[u][c];
}
}
string query(string s){
int u = 0, n = s.length();
int i;
for(i = 0 ; i < n ; i++){
int c = s[i] - 'a';
if(val[u] == 1) //找出第一个值为1的节点
break;
u = ch[u][c];
}
return s.substr(0,i); //返回该子串
}
void output(){
for(int i=0;i<word_num;i++)
cout<<words[i]<<" "<<query(words[i])<<endl;
}
void getword(string str,int i){
words[i] = str;
}
void set_word_num(int k){
word_num = k;
}
private:
int ch[max_nodes][characters]; //存放节点
int val[max_nodes]; //存放每个节点的值
int sz;
int word_num; //单词数
string words[max_words]; //保存单词的数组
};
int main(){
Trie trie;
string str;
int count = 0;
while(cin>>str){
trie.insert(str);
trie.getword(str, count);
count++;
}
trie.set_word_num(count);
trie.output();
return 0;
}