九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/12258411
求每个单词最短不重复前缀
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <math.h>
#include <queue>
#define ll int
using namespace std;
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}
#define Word_Len 10000
#define Sigma_size 30
int ch[Word_Len][Sigma_size]; //Word_Len是字典树的节点数 若都是小写字母Sigma_size=26
int Have_word[Word_Len]; //这个节点下有几个单词
int val[Word_Len]; // 这个节点附带的信息,初始化为0表示这个节点不存在单词,所以节点带的信息必须!=0
int sz ; //当前节点数
//初始化字典树
void init(){
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
memset(Have_word, 0, sizeof(Have_word));
}//初始化
int idx(char c){ return c-'a';} //字符串编号
void Creat(char *s){
int u = 0, len = strlen(s);
for(int i = 0; i < len; i++){
int c = idx(s[i]);
if(!ch[u][c]){ //节点不存在
memset(ch[sz], 0, sizeof(ch[sz]));
ch[u][c] = sz++;
}
u = ch[u][c];
Have_word[u]++;
}
}
void find_ans(char *s){
int u = 0, len = strlen(s);
for(int i = 0; i < len; i++){
int c = idx(s[i]);
u = ch[u][c];
printf("%c",s[i]);
if(Have_word[u]==1) return ;
}
}
char S[1002][25];
int n;
int main(){
n=0;
init();
while(~scanf("%s",S[n])){
Creat(S[n]);
n++;
}
for(int i=0;i<n;i++){
printf("%s ",S[i]);
find_ans(S[i]);
printf("\n");
}
return 0;
}