题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1075
题目大意:
给你一本火星词典,每个火星单词对应一个英文单词。
然后给你一篇火星文章,要求你翻译成英文。
要求如下:
如果这个火星单词用英文单词可以表示,就翻译成英文,如果没有这个单词,就原样输出。遇到标点符号或者空格原样输出即可。
解题思路:
字典树的变形而已。
难点就在于对这篇文章的处理上。处理好这点,这道题就是一道水题了。。。
我在文章处理上花费了好大一番功夫才搞定。。。。。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define N 3010
struct Tire //字典树,dic存英文含义
{
char dic[11];
Tire *next[26];
};
Tire *head;
void init() //初始化
{
head = new Tire;
head->dic[0] = '*';
for(int i = 0; i < 26; ++i)
head->next[i] = NULL;
}
void insert(char eng[], char mar[]) //插入英文,火星字典
{
int temp, len;
Tire *cur;
len = strlen(mar);
cur = head;
for(int i = 0; i < len; ++i)
{
temp = mar[i] - 'a';
if(cur->next[temp] == NULL)
{
cur->next[temp] = new Tire;
cur = cur->next[temp];
cur->dic[0] = '*';
for(int j = 0; j < 26; ++j)
cur->next[j] = NULL;
}
else
cur = cur->next[temp];
}
strcpy(cur->dic, eng); //保存英文含义
}
void del(Tire *head) //动态建树,用完释放内存
{
for(int i = 0; i < 26; ++i)
if(head->next[i] != NULL)
del(head->next[i]);
delete(head);
}
string search(string mar) //查找火星词典
{
int len, temp;
Tire *cur;
len = mar.length();
cur = head;
for(int i = 0; i < len; ++i)
{
temp = mar[i] - 'a';
if(cur->next[temp] == NULL)
return mar;
cur = cur->next[temp];
}
if(cur->dic[0] == '*')
return mar;
return cur->dic;
}
int main()
{
init();
char dic[10];
char eng[11], mar[11]; //英文,火星文
char history[N]; //火星文章
string word;
string answer; //文章结果
answer = "";
word = "";
scanf("%s", dic);
while(scanf("%s", eng) && strcmp(eng, "END") != 0) //插入火星字典
{
scanf("%s", mar);
insert(eng, mar);
}
scanf("%s", dic);
getchar();
while(gets(history) && strcmp(history, "END") != 0) //火星文章
{
int len;
len = strlen(history);
answer = ""; //翻译结果
for(int i = 0; i < len; ++i)
{
if(history[i] >= 'a' && history[i] <= 'z') //取出每个单词
word += history[i];
else
{
answer += search(word); //翻译单词
word = ""; //清空
answer += history[i]; //加入标点
}
}
cout<<answer<<endl;
}
del(head); //释放内存
return 0;
}
静态建树:
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
int num;
struct Tire //字典树,dic存英文含义
{
char dic[11];
Tire *next[26];
}*cur;
Tire Head[500100]; //不知道有几篇火星文章,所以不知道开多大,折磨的欲死欲活啊。。开到50W才过~~~
void insert(char eng[], char mar[]) //插入英文,火星字典
{
int temp, len;
len = strlen(mar);
cur = &Head[0];
for(int i = 0; i < len; ++i)
{
temp = mar[i] - 'a';
if(cur->next[temp] == NULL)
{
cur->next[temp] = &Head[++num];
cur = cur->next[temp];
cur->dic[0] = '*';
}
else
cur = cur->next[temp];
}
strcpy(cur->dic, eng); //保存英文含义
}
string search(string mar) //查找火星词典
{
int len, temp;
len = mar.length();
cur = &Head[0];
for(int i = 0; i < len; ++i)
{
temp = mar[i] - 'a';
if(cur->next[temp] == NULL)
return mar;
cur = cur->next[temp];
}
if(cur->dic[0] == '*')
return mar;
return cur->dic;
}
int main()
{
//freopen("Input.txt", "r", stdin);
char dic[10];
char eng[11], mar[11]; //英文,火星文
char history[3010]; //火星文章
string word;
string answer; //文章结果
answer = "";
word = "";
num = 0;
scanf("%s", dic);
while(scanf("%s", eng) && strcmp(eng, "END") != 0) //插入火星字典
{
scanf("%s", mar);
insert(eng, mar);
}
scanf("%s", dic);
getchar();
while(gets(history) && strcmp(history, "END") != 0) //火星文章
{
int len;
len = strlen(history);
answer = ""; //翻译结果
for(int i = 0; i < len; ++i)
{
if(history[i] >= 'a' && history[i] <= 'z') //取出每个单词
word += history[i];
else
{
answer += search(word); //翻译单词
word = ""; //清空
answer += history[i]; //加入标点
}
}
cout<<answer<<endl;
}
return 0;
}