标签:字典树
题链:http://acm.hdu.edu.cn/showproblem.php?pid=1671
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
NO YES
题意:给出n串字符串,问其中是否会有某串字符串是另一个字符串的前缀。
做法:不断加到Trie里,然后不断判断是不是其他字符串的前缀,或者已有的是不是自己的前缀。
#include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX 10 struct Trie { Trie *next[MAX]; int v; //根据需要变化 }; Trie root; void createTrie(char *str) { int len = strlen(str); Trie *p = &root, *q; for(int i=0; i<len; ++i) { int id = str[i]-'0'; if(p->next[id] == NULL) { q = (Trie *)malloc(sizeof(Trie)); q->v = 1; //初始v==1 for(int j=0; j<MAX; ++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; //若为结尾,则将v改成-1表示 } int findTrie(char *str) { int len = strlen(str); Trie *p = &root; if(p==NULL) return 0; for(int i=0; i<len; ++i) { int id = str[i]-'0'; p = p->next[id]; if(p == NULL) //若为空集,表示不存以此为前缀的串 return 0; if(p->v == -1&&i==len-1) //有一样的串 return -1; if(p->v == -1)//字符集中已有串是此串的前缀 return -1; } return -1; //此串是字符集中某串的前缀 } int dealTrie(Trie* T) { int i; if(T==NULL) return 0; for(i=0;i<MAX;i++) { if(T->next[i]!=NULL) { dealTrie(T->next[i]); T->next[i]=NULL; } } if(T!=&root) free(T); return 0; } char str[100]; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int flag=1; while(n--) { scanf("%s",str); int tem=findTrie(str); if(tem==-1) flag=0; createTrie(str); } if(flag==0) puts("NO"); else puts("YES"); dealTrie(&root); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:字典树
原文地址:http://blog.csdn.net/u013532224/article/details/46777745