给你一堆字符串,让你输出每个字符串着这些字符串中可以单独识别的前缀。因为是直接找的字典树的题目来做,所i就是用字典树了。
字典树的每一个结点记录某一个字符出现的次数,之后,遍历每一个字符串,当出现第一个次数为1的点,则记录下来,输出从字符串头到这个点的字符,则为这个字符串的独立前缀。
交了N多次,一直在WA,很纠结,最后更新了首节点的数量,才AC 的,好痛苦的经历。
#include <cstdio> #include <cstdlib> #include <cstring> const int branchNum = 26; const int trieNodeNum = 21000; struct Trie_node{ int isStr; int next[branchNum]; }trie[trieNodeNum]; int trieTop = 0; void init(){ int i; trieTop = 0; for (i = 0; i < trieNodeNum; i++){ trie[i].isStr = 0; for (int j = 0; j < 26; j++){ trie[i].next[j] = -1; } } } void insert(const char *word){ int location = 0; trie[location].isStr ++; //要先添加一个,即是trie第一个结点的个数要加一,不然会WA while (*word){ if (trie[location].next[*word - 'a'] == -1){ trie[location].next[*word - 'a'] = ++trieTop; } location = trie[location].next[*word - 'a']; trie[location].isStr ++; // printf("location: %d\n", trieTop); word++; } //trie[location].isStr = true; } bool search(const char *word){ int location = 0; while (*word && location != -1){ location = trie[location].next[*word - 'a']; word ++; } return location != -1 && trie[location].isStr == 0; } void print(const char *word){ int location = 0; const char *a = word; while (*word && location != -1){ location = trie[location].next[*word - 'a']; printf("%d %c %d\n", word - a, *word, trie[location].isStr); word++; } } char str[1100][30]; int prefix[1100]; int search_prefix(const char *word){ int last = 0; int location = 0; int len = 0; const char *a = word; while (*word && trie[location].isStr){ if (trie[location].isStr == 1){ last = len; break; } location = trie[location].next[*word - 'a']; word++; len ++; } if(last == 0){ last = strlen(a); } // printf("\nlast : %d\n", strlen(word)); return last; } int main(void){ int len = 0; int i; init(); while (scanf("%s", str[len]) != EOF){ insert(str[len]); len++; } for (i = 0; i < len; i++){ prefix[i] = search_prefix(str[i]); printf("%s ", str[i]); for (int j = 0; j < prefix[i]; j++){ printf("%c", str[i][j]); } printf("\n"); } return 0; }