1. 单词a中任意字母交换位置变为单词b,我们就称单词a,b为兄弟单词,如 army 与 mary为兄弟单词。现给一个单词字典,用户输入一个单词,找出字典中所有的兄弟单词,请写出你的解题思路和算法。
【解题思路】:在编程珠玑上第二章结束出有此题的解析(18-19页),首先将字典里的单词做这样的处理
如字典有:pans pots opt snap stop tops
处理结果如下:
格式A:B C D E ……,其中A是排序后的单词,BCDE是所有的兄弟单词
ansp: pans snap
opst: pots stop tops
opt: opt
其中前面是单词本身排序后的结果,后面是此排序结果下所有的兄弟单词。
现在难点在给出一个单词,怎么查找在处理结果中的排序后A字段
这里用到字典树,代码如下:
#define WORDMAX 100 struct my { char word[256]; char sig[256]; } wo[WORDMAX]; struct word_index { int len; char word[256]; char brother[WORDMAX][256]; } you[WORDMAX]; char oldsig[256]; bool cmp(my a, my b) { if (strcmp(a.sig, b.sig) < 0) return true; return false; } struct trie { int cnt; int index; trie *p[26]; } * root; void make_tree(char *s, int index) { trie * r = root; trie * tmp; int i, j; int len = strlen(s); for (i = 0; s[i] != '\0'; ++i) { if (r->p[s[i] - 'a'] == NULL) { tmp = new trie; tmp->cnt = 0; tmp->index = -1; for (j = 0; j < 26; ++j) tmp->p[j] = NULL; r->p[s[i] - 'a'] = tmp; } r = r->p[s[i] - 'a']; r->cnt++; if (i == len - 1) { r->index = index; } } } void search(char s[]) { trie * r = root; int i; int index, len; for (i = 0; s[i] != '\0'; ++i) { r = r->p[s[i] - 'a']; if (r == NULL) { break; } } if (i != strlen(s) || r->index == -1) { printf("not found\n"); } else { index = r->index; len = you[index].len; for (i = 0; i < len; ++i) printf("%s ", you[index].brother[i]); printf("\n"); } } int main() { /* sign */ int index = 0; while (scanf("%s", wo[index].word) != EOF) { strcpy(wo[index].sig, wo[index].word); sort(wo[index].sig, wo[index].sig + strlen(wo[index].sig)); ++index; } /* sort */ sort(wo, wo + index, cmp); /* squash */ strcpy(oldsig, ""); int i, j; int distinct = 0; for (i = 0; i < index; ++i) { int flag = 0; if (strcmp(oldsig, wo[i].sig) != 0 && i) { ++distinct; strcpy(you[distinct].word, wo[i].sig); you[distinct].len = 0; strcpy(you[distinct].brother[you[distinct].len], wo[i].word); ++you[distinct].len; flag = 1; } if (i == 0) { strcpy(you[distinct].word, wo[i].sig); you[distinct].len = 0; strcpy(you[distinct].brother[you[distinct].len], wo[i].word); ++you[distinct].len; flag = 1; } strcpy(oldsig, wo[i].sig); if (flag == 0) { strcpy(you[distinct].brother[you[distinct].len], wo[i].word); ++you[distinct].len; } } ++distinct; root = new trie; for (i = 0; i < 26; ++i) { root->index = -1; root->p[i] = NULL; } for (i = 0; i < distinct; ++i) { make_tree(you[i].word, i); } char t[1000]; while (cin>>t) { sort(t, t + strlen(t)); search(t); } return 0; } /* pans pots opt snap stop tops */