link to original topic
Analysis of http://acm.hdu.edu.cn/showproblem.php?pid=1671 problems
The question requires us to determine if there are strings in the string that are prefixed by other strings. A dictionary tree is used in this topic, and the structure of the dictionary tree is very convenient for dealing with string prefixes. Consider three main scenarios:
(1) The previously inserted string is the prefix of the current string: for example, before inserting the string "911" into the dictionary tree, the currently inserted string is "9110". When the current string "9110" is inserted in the third character ' 1 ', it is found that the V value of the node is ' 1 ', which indicates the end of a string. Returns 0 directly, no longer inserts the character (and no new node exists), and outputs No.
(2) The currently inserted string is prefixed with the previously inserted string: For example, the string "9110" was previously inserted, and the currently inserted string is "911". At this point, set a variable isOK, the initial value is 0, only when the new node, isOK will be 1. Obviously, the current insert "911" does not need to create a new node, know that the last character is inserted ' 1 ', the value of isOK is also 0, this time return isOK, indicating inconsistent, output No.
(3) No prefix exists, new node is inserted during string insertion, isok=1, output yes.
Note: A case is determined to release the memory used by the case's dictionary tree, otherwise, it will be out of memory range. AC Code
# include<stdio.h> # include<string.h> # include<malloc.h> # define MAX typedef struct trie{str
UCT Trie * Next[max];
Char v;//is ' 1 ', expressed as the last character of the string, otherwise the middle character of the string is}trie;
int isconsistent (Trie * * Root,char num[]);
void Myfree (Trie * * root);
int main () {char num[11];
int t,n,i;
Trie * ROOT;
scanf ("%d", &t);
while (t--) {root=null;
int flag=1;
scanf ("%d", &n);
for (i=0;i<n;i++) {scanf ("%s", num);
if (flag) {flag=isconsistent (&root,num);
}} if (flag) printf ("yes\n");
else printf ("no\n");
Myfree (&root);
} return 0; }//To determine whether a string is a prefix of another string.
If yes, returns 0, otherwise, 1 is returned.
int isconsistent (Trie * * Root,char num[]) {int I,len=strlen (num), J; isOK is only 1 when a new node is inserted. If no new node has been inserted,//indicates that the string is prefixed with one of the preceding strings.
For example, before inserting the string "9110",//Now the string is "911", at this time do not need to create a new node, just step by step down through both. TraverseAfter "911", isOK is still 0.
If the last character of a string, such as ' 91 ', is encountered during traversal, then//will return 0 directly and no longer insert the last ' 1 ' of ' 911 '.
int isok=0;
if (*root==null) {*root= (Trie *) malloc (sizeof (Trie));
For (i=0;i<max;i++) (*root)->next[i]=null;
(*root)->v= ' 0 ';
} Trie *p=*root;
for (i=0;i<len;i++) {int id=num[i]-' 0 ';
if (p->next[id]==null) {p->next[id]= (Trie *) malloc (sizeof (Trie));
p=p->next[id];
p->v= ' 0 ';
isok=1;
for (j=0;j<max;j++) p->next[j]=null;
} else {p=p->next[id];
if (p->v== ' 1 ') return 0;//the string prefix in the string inserted earlier, for example, insert the string "911" earlier, and now insert the string "9110".
}} p->v= ' 1 ';
return isOk;
} void Myfree (Trie * * root) {Trie *p=*root;
int i; for (i=0;i<max;i++) {if (p->next[i]!=null) {Myfree (& (p->next[I]));
}} free (p);
P=null;
}