该题目最初的想法是将没一行的字典数据用string接收,然后存入vector数组中。
然后题目的问题只变成了从vector的每个元素中查找火星人说的话,然后用英语替代。
可是写完后,时间顿时报表。原来是搜索占据了太大的时间。
下面是超时代码:
#include<iostream>
#include<string>
#include<vector>
#include<cstring>
using namespace std;
void translate(vector<string> &vec1,char *str);
int main()
{
string str;
int i = 0;
int ch;
char str1[11111];
vector<string>vec1;
getline(cin,str);//接收START
getline(cin,str);//接收字典数据
while(str != "END")//将END之前的字典数据存入容器中
{
vec1.push_back(str);
getline(cin,str);
}
getline(cin,str);//接收start
//采用别接收别翻译的方法来做,比较简单
ch = cin.get();
while(ch!='E')
{
i=0;
while( ch>='a' && ch<='z')
{
str1[i] = ch;
ch = cin.get();
i++;
}
str1[i] = 0;//添加0结束标志
if(i!=0)
translate(vec1,str1);//翻译
cout<<str1;//输出翻译之后的字符串
cout<<(char)ch;//跳出循环的原因是因为接收到了标点符号,或者空格,或者回车
ch = cin.get();
}
cin.get();
cin.get();
}
void translate(vector<string>&vec1,char *str)
{
int i;
int j;
bool mark = false;//用来标记死否找到
int pos = 0;
for(i=0;i!=vec1.size();++i)
{
pos = vec1[i].find(str);
if( pos != string::npos)
{
mark = true;
break;
}
}
if(mark && vec1[i][pos-1]==' ' &&vec1[i].size() == pos+strlen(str))
{
for(j=0;j!=vec1[i].size() && vec1[i][j]!=' ';++j)
{
str[j] = vec1[i][j];//翻译
}
str[j] = 0;//添加结束标志
}
}
看了题目后的讨论是说要用关联容器map或者字典树来做,可是这两者我都没有学过。
于是花了一个自修的时间学了map容器。
实现了下面的代码:
#include<iostream>
#include<sstream>
#include<string>
#include<map>
using namespace std;
void find(map<string,string>&dictionary,string str)
{
map<string,string>::iterator iter;
iter = dictionary.find(str);
if(iter != dictionary.end())
cout<<dictionary[str];
else
cout<<str;
}
int main()
{
map<string,string> dictionary;//用来做字典
map<string,string>::iterator iter ;
string::iterator siter;
string line;
string word1,word2;
char ch;
int i;
getline(cin,line);//接收START
getline(cin,line);//接收字典数据
while(line != "END")//没遇到END之前的数据都要加入字典
{
istringstream stream(line);//从每行中读取单词
stream>>word1;//读取值
stream>>word2;//读取键
dictionary[word2] = word1;//插入字典
getline(cin,line);//接收新的数据
}
iter = dictionary.begin();
getline(cin,line);//接收start
getline(cin,line);
while(line != "END")
{
for(i=0;i<line.size();++i)//接收行数据
{
ch = line[i];
if(ch<='z' ||ch>='a')
{ string str;
while(i<line.size() && ch>='a' &&ch<='z')//提取每行的单词
{
str.push_back(ch);
++i;
ch = line[i];
}
find(dictionary,str);//替换单词,输出
cout<<ch;//输出非单词字符
}
else
cout<<ch;
}
cout<<endl;
getline(cin,line);
}
}
字典树 还没学,等有空学了再来重写代码。
提交了下别人用字典树写的代码,运行时间只有我用map容器的1/6
所以我一定要学会字典树。
好不容易学了字典树,重写代码,一提交,是比用map容器快多了,但是比别人用字典树写的代码慢多了。
一研究,原来是数据太大,而我又用C++的输入函数来录入数据,导致时间太慢,
所以以后录入大数据时,一定要用C语言的输入函数。
下面是字典树写的代码:
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
const int MAX = 26;
struct node
{
string word;//火星文对应的英文
node *next[MAX];
node()
{
for(int i=0;i!=MAX;++i)
{
next[i] = NULL;
}
}
};
class trie//字典树类
{
public:
trie(){root = new node;}
void creat_trie(string str,string word);
void search(string str);
void print_all();
private:
node *root;
};
void trie ::creat_trie(string str,string word)//字典树的创建
{
node *current = root;
node *fresh;
int index;
for(int i=0;i<str.size();++i)
{
index = str[i] - 'a';
if(current->next[index] == NULL)
{
fresh = new node;
current->next[index] = fresh;
current = current->next[index];
}
else
{
current = current->next[index];
}
}
current->word = word;
}
void trie:: search(string str)
{
node *current;
current = root;
int index;
for(int i=0;i!=str.size();++i)//能够跳出循环说明了什么?说明该单词在字典树种或该单词是字典树中某个单词的前缀
{
index = str[i] - 'a';
current = current->next[index];
if(current == NULL)
{
cout<<str;
return;
}
}
//判断跳出循环的条件是为何
if(current->word == "")//该单词是字典树中某个单词的前缀,即字典树中无该单词,不能翻译
cout<<str;
else//翻译
cout<<current->word;
}
int main()
{
string line;
string word1,word2;
char ch;
int i;
trie t;
cin>>line;//接收START
cin>>word1;
cin>>word2;
while(word1 != "END")//没遇到END之前的数据都要加入字典
{
t.creat_trie(word2,word1);
cin>>word1;//读取值
cin>>word2;//读取键
}
//第二个shart会被word2所读取
cin.get();//接收回车
getline(cin,line);//接收火星人的话
while(line != "END")
{
for(i=0;i<line.size();++i)//接收行数据
{
ch = line[i];
if(ch<='z' ||ch>='a')
{ string str;
while(i<line.size() && ch>='a' &&ch<='z')//提取每行的单词
{
str.push_back(ch);
++i;
ch = line[i];
}
t.search(str);
cout<<ch;//输出非单词字符
}
else
cout<<ch;
}
cout<<endl;
getline(cin,line);
}
}