第十一章 11.3.6节练习

练习11.33

实现你自己版本的单词转换程序。

解答:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <map>

using namespace std;

map<string, string>buildMap(ifstream &map_file){
	map<string, string> trans_map; //保存转换规则
	string key; // 要替换的单词
	string value; // 替换后的内容
	// 读取第一个单词存入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){
	// 实际的转换工作;此部分是程序的核心
	auto map_it = m.find(s);
	// 如果单词在转换规则map中
	if (map_it != m.cend()){
		return map_it->second;  // 使用替换短语
	}
	else{
		return s;  // 否则返回原string
	}
}

void word_transform(ifstream &map_file, ifstream &input){
	auto 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 << " ";
			}
			// transform返回它的第一个参数或其转换之后的形式
			cout << transform(word, trans_map); // 打印输出
		}
		cout << endl;
	}
}

int main(){
	ifstream map_file("map.txt");
	ifstream input("input.txt");
	word_transform(map_file, input);
}
这里还是将书上的程序组合在了一起。

作为primer的学习资料,这里需要去单步调试来了解整个程序的运行流程。

而非再去写一个。当然,在时间允许的情况下,可以配合着系统的API将这个程序进行重写。


练习11.34

如果你将transform函数中的find替换为下标运算符,会发生什么情况?

解答:

不能直接进行替换,这里find是返回一个pair迭代器,而下标运算符则会返回一个string的值。

如果要改的话,下面的if语句也要对应的换成有equal_range的for循环语句。


练习11.35

在buildMap中,如果进行如下改写会有什么效果?

trans_map[key] = value.substr(1);

改为

trans_map.insert({key, value.substr(1)});

解答:

根据11.3.2节学到的内容来判断,这里的替换操作应为等价操作。


练习11.36

我们的程序没有检查输入文件的合法性。特别是,它假定转换规则文件中的规则都是有意义的。如果文件中的某一行包含一个关键字、一个空格,然后就结束了,会发生什么?

预测程序的行为并进行验证,再与你的程序进行比较。

解答:

不会对其他规则和文本翻译有影响。

空行不会包含在替换key中;当只有一个关键字的时候key对应的值是空的,也就是不会进行转换。

所以,规则文件的鲁棒性在这里还是挺高的。

我比较担心字符集的问题,当不同的字符在这里出现的时候,程序也许会出现问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值