题意:给定字符串集合,求每个串最短的能区别于其他字符串的前缀,如“carbohydrate”能缩短成“carboh”,但不能缩短成“carbo“,因为集合中有别的串也有相同前缀。
思路:模板题
反思:套用模板要小心,情况不同时某些细节也要因此调整,万不可大意。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 26;
char s[1000 * 2][20 * 2];
struct Trie
{
int v;
Trie* next[MAXN];
};
Trie* root;
void InsertTrie(char* str)
{
int len = strlen(str);
Trie* p = root;
for(int i = 0; i < len; i++)
{
int id = str[i] - 'a';
if(p -> next[id] == NULL)
{
Trie* q = new Trie;
q -> v = 1;
for(int j = 0; j < MAXN; j++)
{
q -> next[j] = NULL;
}
p -> next[id] = q;
p = p-> next[id];
}
else
{
p -> next[id] -> v++;
p = p -> next[id];
}
}
return;
}
void DelTrie(Trie* T)
{
if(T == NULL) return;
for(int i = 0; i < MAXN; i++)
{
if(T -> next[i] != NULL)
DelTrie(T -> next[i]);
}
delete T;
return;
}
void SearchTrie(char* str)
{
int len = strlen(str);
Trie* p = root;
for(int i = 0; i < len; i++)
{
int id = str[i] - 'a';
p = p -> next[id];
if(p -> v == 1)
{
cout << str[i];
break;
}
else
{
cout << str[i];
}
}
cout << endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
root = new Trie;
for(int i = 0; i < MAXN; i++)
{
root -> next[i] = NULL;
}
int n = 0;
while(cin >> s[n])
{
InsertTrie(s[n]);
n++;
}
for(int i = 0; i < n; i++)
{
cout << s[i] << " ";
SearchTrie(s[i]);
}
DelTrie(root);
return 0;
}