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
*/