来说说C++ Primer上的word-transformation map(翻译小程序)

来源:互联网 发布:井冈山大学网络教育 编辑:程序博客网 时间:2024/06/11 21:45

简介:

有一个map_file.txt文件是用来储存翻译规则的,就像这样:

brb be right back

k okay?

y why

r are

u you

pic picture

thk thanks!

l8r later

还有一个input.txt文件里面就是要翻译的内容, 就像这样:

where r u

y don't u send me a pic

k thk l8r

这个程序作用就是把这些奇形怪状的文字翻译成给人看的文字,翻译结果如下:

where are you

why don't you send me a picture

okay? thanks! later


那么我们就来看看这个程序吧!

这个程序一共由三个函数组成,我们分别来看看吧。

首先是这个word_transform函数。它是主角。它的参数是两个ifstream&。传进来的一个是map_file, 另一个是input。关于这两个文件之前已经做过说明了。

void word_transform(ifstream& map_file, ifstream& input) {/*定义一个map用来存放map_file里面的 键-值 对。buildMap函数的作用就是把map_file.txt里面的 键-值 对提出来存放入map中。*/map<string, string> trans_map = buildMap(map_file);string text;//input.txt文件中的数据是被一行一行地读出来的。text存的是一整行。while (getline(input, text)) {//用istringstream和text关联。istringstream stream(text);string word;/*在这里,要进行单词的输出。因为每个单词之后都要有空格(没有空格的话这句话没法看的)。因此输出第一个单词之后就要开始加空格然后再输出单词。在这里我们用bool来判断。*///第一个单词未输出时 bool firstWord 为true。bool firstWord = true;while (stream >> word) {if (firstWord) {//要输出第一个单词了,把firstWord设置为false。firstWord = false;}//只要firstWord为false他就会先输出空格再输出单词。else {cout << " ";}//输出单词之前先用transform函数进行翻译。cout << transform(word, trans_map);}//输出完一句话就换个行。cout << endl;}}

然后是buildMap函数,它负责将map_file.txt里面的键-值对提取出来存入map。

map<string, string> buildMap(ifstream& map_file) {map<string, string> trans_map;string key, value;//先将key读进来,再将这一行中key后面的全部东西读进来。while (map_file >> key && getline(map_file, value)) {//因为key和value中间是有一个空格的。所以size大于1就代表value里面是有东西的。if (value.size() > 1) {/*map中创建新键并赋值。因为开头是一个空格而这个空格是不需要的。因此赋的值要从该字符串下标为1处开始。于是要用substr(1)。*/trans_map[key] = value.substr(1);}else {//value为空的话就抛出异常。throw runtime_error("no rule for " + key);}}//该函数返回这个map。return trans_map;}

接下来是transform函数。它负责翻译。其实就是根据输入文件中的关键字来寻找map中对应的单词,然后返回这个单词。

const string& transform(const string& s, const map<string, string>& m) {/*用map的find函数来寻找对应的key。它返回的是指向所需位置的迭代器。如果找不到就返回.end()。*/map<string, string>::const_iterator map_it = m.find(s);if (map_it != m.cend()) {//如果找到了就返回这个pair的第二个元素,也就是我们要的value。return map_it->second;}else {//没找到的话就返回传进来的那个字符串本身。return s;}}

那么最后我们就来看看整合版吧。

#include <iostream>#include <map>#include <fstream>#include <string>#include <sstream>using namespace std;map<string, string> buildMap(ifstream&);const string& transform(const string&, const map<string, string>&);void word_transform(ifstream&, ifstream&);int main() {ifstream map_file("map_file.txt"), input("input.txt");word_transform(map_file, input);getchar();return 0;}void word_transform(ifstream& map_file, ifstream& input) {map<string, string> trans_map = buildMap(map_file);string text;while (getline(input, text)) {istringstream stream(text);string word;bool firstWord = true;while (stream >> word) {if (firstWord) {firstWord = false;}else {cout << " ";}cout << transform(word, trans_map);}cout << endl;}}map<string, string> buildMap(ifstream& map_file) {map<string, string> trans_map;string key, value;while (map_file >> key && getline(map_file, value)) {if (value.size() > 1) {trans_map[key] = value.substr(1);}else {throw runtime_error("no rule for " + key);}}return trans_map;}const string& transform(const string& s, const map<string, string>& m) {map<string, string>::const_iterator map_it = m.find(s);if (map_it != m.cend()) {return map_it->second;}else {return s;}}

这里是运行结果:


0 0