1.我去,分成两个单词的方法竟然这么暴力,挨个试。。。不过很有效,不要一到字符串匹配就kmp,本来写个trie就够长了,再写kmp太复杂,而且根本没法写。所以遇题可以先想想暴力,不行再换别的姿势。
2.最坑的地方在于根本不用管输出顺序,因为输入就是字典序,输出必然是。
3.trie树还真是空间换时间。长度最多也就30,insert和find就循环30次,所以他敢用暴力套3个for循环,所以就算如此,所需时间也比你想象的少得多。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node{
struct node*next[26];
bool exist;
int count;
}*trie,node;
trie root;
char s[50005][100];
void creat(trie &p){
p=(trie)malloc(sizeof(node));
for(int i=0;i<26;i++)
p->next[i]=0;
p->exist=false;
p->count=0;
}
void insert(trie p,char s[]){
int k=0 ;
while(s[k]!='\0'){
if(!p->next[s[k]-'a']){
trie q;
creat(q);
p->next[s[k]-'a']=q;
}
p=p->next[s[k]-'a'];
p->count++;
k++;
}
p->exist=true;
}
int find(trie p,char s[]){
int k=0;
while(s[k]!='\0'&&p->next[s[k]-'a']){
p=p->next[s[k]-'a'];
k++;
}
if(s[k]=='\0')
return p->exist;
else return 0;
}
int main(){
char s1[100],s2[100];
int n,i,j,k;
creat(root);
while(scanf("%s",s[n])!=EOF){
insert(root,s[n]);
n++;
}
for(i=0;i<n;i++){
for(j=0;j<strlen(s[i]);j++){
for(k=0;k<j;k++){
s1[k]=s[i][k];
}
s1[j]='\0'; /*生成新的串别忘了'\0'*/
strcpy(s2,s[i]+j); /*又是这种姿势*/
if(find(root,s1)&&find(root,s2)){
printf("%s\n",s[i]);
break;
}
}
}
return 0;
}