在每一个结点里存一个计数器,添加的时候当每次这个结点被访问到时候,自增计数器.
然后对每一个单词进行一次查找,找到字母路径上第一个计数器为1的结点为止,这样就保证了最短的唯一前缀.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <map>
using namespace std;
struct node{
int cnt;
node * child[26];
}ns[95 * 26], *root;
int cnt;
char buf[30];
vector<string>v1;
void init(){
v1.clear();
memset(ns, 0, sizeof(ns));
cnt = 1;
root = &ns[0];
}
void addWord(char * str){
int len = strlen(str);
node * p = root;
for (int i = 0; i < len; ++i){
p->cnt++;
int idx = str[i] - 'a';
if(p->child[idx] == NULL){
p->child[idx] = &ns[cnt++];
}
p = p ->child[idx];
}
p->cnt++;
}
string getPrefix(const char * str){
int len = strlen(str);
node * p = root;
string anStr;
for (int i = 0; i < len; ++i){
p = p->child[str[i] - 'a'];
if(p->cnt <= 1){
return string(str, str + i + 1);
}
}
return string("");
}
int main(){
int T;
scanf("%d\n\n", &T);
while (T--){
init();
while (gets(buf) && strcmp(buf, "")){
v1.push_back(buf);
addWord(buf);
}
for (int i = 0; i < (int)v1.size(); ++i){
string ans = getPrefix(v1[i].c_str());
if(ans == "")printf("%s %s\n", v1[i].c_str(), v1[i].c_str());
else printf("%s %s\n", v1[i].c_str(), ans.c_str());
}
if(T)printf("\n");
}
return 0;
}