hdu 1075 What Are You Talking About 字典树(静态版)

时间:2021-05-26 19:31:45

HDU1075

-------千万别让不开心的事影响了自己正常的生活,今天遇到了尴尬的事情,郁闷了一晚上没看书,就只是快要熄灯了做完我的每日一水题


         《What Are You Talking About》看起来感觉好复杂的样子,一看Time LimitMemory Limit果断放心做了。wa了几次,最后在一通乱改中AC现在还是不太明白希望有看到的帮忙分析下(标注在了代码中)。


        题意:第一个START 和 END 之间的每行两个字符串,意思是后面的(火星的)单词可以翻译成前面的(地球的)单词。第二个START 和 END 之间的每行一个长字符串代表火星的文章,让你翻译成地球文输出。

        

         思路:把每个火星单词放入字典树,每个火星单词的尾节点存上对应的地球单词作为最后查找用,然后就是翻译阶段,把所有连续的小写字母组成的字符串存在一个字符数组中查找该单词是否有对应的地球单词,有则输出翻译结果,否则原样输出,剩下的除了小写字母之外的字符全都原样输出。


         字典树的意思就是先给一个根节点,然后顺着这条根节点往下连接儿子节点的那条边作为单词的一个字母,如果存在这个字母就下去找那个儿子节点,然后同理找下一个字母。不存在这个字母的话,根节点就再生一个儿子,然后继续不断地生..查找同理,字母不存在就说明没这个单词



本题代码


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <map>
#include <algorithm>
using namespace std;
char s[12], s2[12];
char val[1000000][26];
int ch[1000000][26];
int tmp;
void insert(char *a, char *b)
{
int rt = 0, x;
for (int i = 0; a[i]; i++)
{
x = a[i] - 'a';
if (ch[rt][x] == 0)
{
strcpy(val[tmp], "");
ch[rt][x] = tmp++;
}
rt = ch[rt][x];
}
strcpy(val[rt], b);
}
void find(char *ss)
{
int rt = 0, x;
for (int i = 0; ss[i]; i++)
{
x = ss[i] - 'a';
if (ch[rt][x] == 0)
{
printf("%s", ss);
return ;
}
rt = ch[rt][x];
}
if (strcmp(val[rt], "") != 0)//我不解的是为什么这里要判断下val[rt]的内容才能输出,而不是直接输出val[rt];
printf("%s", val[rt]);
else
printf("%s", ss);
}
int main()
{
tmp = 1;
strcpy(val[0], "");
memset(ch[0], 0, sizeof(ch[0]));
while (scanf("%s", s) != EOF)
{
if (strcmp(s, "START") == 0) continue;
else if (strcmp(s, "END") == 0) break;
else
{
scanf("%s", s2);
insert(s2, s);
}
}

getchar();
char str[3001];

while(gets(str))
{
if(strcmp(str,"START") == 0) continue;
else if(strcmp(str,"END") == 0) break;
else
{
int tt = 0, t = 0;
for(int i = 0; str[i]; i++)
{
if(str[i] >= 'a' && str[i] <= 'z')
{
if(tt == 0)
tt=1;
s[t++] = str[i];
}
else
{
if(tt == 1)
{
tt = 0;
s[t] = 0;
t = 0;
find(s);
}
printf("%c", str[i]);
}
}
if(tt == 1)
{
s[t] = 0;
find(s);
}
}
printf("\n");
}
return 0;
}