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

简介:

有一个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;
	}
}

这里是运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值