百度实习笔试题解析(第一题)(2012.05.06)

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

你可能感兴趣的:(百度实习笔试题解析(第一题)(2012.05.06))