要求输出每个单词在不产生歧义的情况下的最短前缀,直接构造出一颗字典树就可以了。先执行插入操作,对每一个单词经过的路径都进行一个自增的操作。再一次搜索每一个单词,当其遇到覆盖次数为一,或者是到了单词末尾就输出。
代码如下:
#include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int N, idx; char s[1005][25], rec[25]; struct Node { int cnt, ch[26]; }e[30000]; int init() { ++idx; memset(e+idx, 0, sizeof (e[0])); return idx; } void insert(int p, char *in) { if (*in != '\0') { if (e[p].ch[*in-'a'] == 0) { e[p].ch[*in-'a'] = init(); } ++e[ e[p].ch[*in-'a'] ].cnt; insert(e[p].ch[*in-'a'], in+1); } } void search(int p, char *in, int deep) { if (*in == 0 || e[p].cnt == 1) { rec[deep] = '\0'; } else { rec[deep] = *in; search(e[p].ch[*in-'a'], in+1, deep+1); } } int main() { int Root, ca = 0; while (scanf("%d", &N) == 1) { idx = 0; Root = init(); for (int i = 1; i <= N; ++i) { scanf("%s", s[i]); insert(Root, s[i]); } printf("***Case %d\n", ++ca); for (int i = 1; i <= N; ++i) { printf("%s ", s[i]); search(Root, s[i], 0); puts(rec); } } return 0; }