有几个地方要注意
1.分割字符串的细节
2.可能需要按字母表排序
3.搜索字典树的时候不要搜成了前缀,注意是一个字符串的终结
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1247
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define maxn 30
using namespace std;
char a[50005][205];
char ans[50005][205];
struct Trie{
Trie * next[maxn];
int v;
};
Trie * root;
int cmp(const void * a1,const void * a2){
char * p1 = (char *)a1;
char * p2 = (char *)a2;
return strcmp(p1,p2);
}
void Init_Trie(){
root = (Trie *)malloc(sizeof(Trie));
for(int i=0;i<maxn;i++){
root -> next[i] = NULL;
}
}
void Add_Trie(char * str){
Trie * p = root , * q;
for(int i=0;str[i]!='\0';i++){
int id = str[i] - 'a';
if(p->next[id]==NULL){
q = (Trie *)malloc(sizeof(Trie));
q -> v = 0;
for(int j=0;j<maxn;j++){
q -> next[j] = NULL;
}
p -> next[id] = q;
p = p -> next[id];
}
else {
//p -> next[id]->v++; //记录有某个共同前缀的单词数量
p = p -> next[id];
}
}
p -> v = 1;
}
int Search_Trie(char * str){
Trie * p = root;
for(int i=0;str[i]!='\0';i++){
int id = str[i] - 'a';
p = p -> next[id];
if(p==NULL){
return 0;
}
}
return p->v;
}
void Del_Trie(Trie * p){
for(int i=0;i<maxn;i++){
if(p->next[i])Del_Trie(p->next[i]);
}
free(p);
}
void Input(){
Init_Trie();
int i = 0;
while(~scanf("%s",a[i++])){
Add_Trie(a[i-1]);
}
int k,kk = 0;
for(int j=0;j<i;j++){
int mark = 0;
for(k=1;k<strlen(a[j]);k++){
char tempa[205];
char tempb[205];
int k1;
for(k1=0;k1<k;k1++){
tempa[k1] = a[j][k1];
}
tempa[k1] ='\0';
for(k1=k;k1<strlen(a[j]);k1++){
tempb[k1-k] = a[j][k1];
}
tempb[k1-k] = '\0';
if(Search_Trie(tempa)&&Search_Trie(tempb)){
mark = 1;
break;
}
}
if(mark){
for(k=0;k<strlen(a[j]);k++){
ans[kk][k] = a[j][k];
}
ans[kk][k] = '\0';
kk++;
}
}
qsort(ans,kk,sizeof(ans[0]),cmp);
for(int i=0;i<kk;i++){
puts(ans[i]);
}
Del_Trie(root);
}
void File(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main(void){
//File();
Input();
return 0;
}