给你一堆字符串,让你输出每个字符串着这些字符串中可以单独识别的前缀。因为是直接找的字典树的题目来做,所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;
}