14.8节练习

14.33 一个重载的函数调用运算符应该接受几个运算对象?

一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所不同即可。


14.34 定义一个函数对象类,令其执行if-then-else的操作:该类的调用运算符接受三个形参,它首先检查第一个形参,如果成功返回第二个形参的值;如果不成功返回第三个形参的值。

#include <iostream>
using namespace std;
class X {
public:
	X() = default;
	X(const int x, const int y, const int z) :a(x), b(y), c(z) {}
	int operator()(const int q, const int w, const int e)
	{
		if (q > 10) {
			return w;
		}
		else {
			return e;
		}
	}
private:
	int a;
	int b;
	int c;
};
int main()
{
	X x, x2;
	cout << x(1, 2, 3) << " " << x2(11, 12, 13);
}

练习14.35 编一个类似于PrintString类,令其从istream中读取一行输入,然后返回一个表示我们所读取的内容的string。如果读取失败,返回空string。

#include <iostream>
#include <string>
using namespace std;
class X {
public:
	X(std::ostream &o = cout, char c = ' ') :os(o), sep(c) {}
	void operator()(const std::string &s) { os << s << sep; }
private:
	std::ostream& os;
	char sep;
};
int main()
{
	string str;
	X x;
	if (getline(cin, str)) {
		x(str);
		cout <<"!" <<endl;
	}
	else {
		x(string());
	}

}

14.36 使用前一个练习定义的类读取标准输入,将每一行保存为vector的一个元素。

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class X {
public:
	X(istream &i = cin, char c = ' ') :is(i), sep(c) {}
	string operator()(string &s) 
	{
		getline(cin, s);
		if (s.size()) {
			return s;
		}
		else {
			return "";
		}
	}
private:
	istream &is;
	char sep;
};
int main()
{
	vector<string> svec;
	string str;
	X line;
	while (line(str)!="") {
		svec.push_back(str);
	}
	for (auto &i : svec) {
		cout << i << "!" << endl;
	}
}

练习14.37 编写一个类令其检查两个值是否相等。使用该对象及标准库算法编写程序,令其替换某个序列中具有给定值得所有实例。


练习14.38 编写一个类令其检查某个给定的string对象的长度是否与一个阈值相等。使用该对象编写程序,统计并报告在输入的文件中长度为1的单词有多少个、长度为2的单词有多少个....、长度为10的单词有多少个。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class string_n {
public:
	string_n(const std::size_t n) :num(n) {}
	bool operator()(const std::string &s)
	{
		return s.size() == num;
	}
private:
	std::size_t num;
};
int main()
{
	vector<std::string> svec{ "paul","pierce","kangkang","c++primer","kobe" };
	for (std::size_t i = 1; i <= 10; ++i) {
		cout << i << " " << count_if(svec.cbegin(), svec.cend(), string_n(i)) << endl;
	}
}


练习14.39 修改上一题的程序令其报长度在1到9间的单词有多少个、长度在10以上的单词又有多少个。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

class string_n {
public:
	string_n(const std::size_t m, const std::size_t n) :max(m), min(n) {}
	bool operator()(const std::string &s)
	{
		return s.size() >= min&&s.size() <= max;
	}
private:
	std::size_t max;
	std::size_t min;
};
int main()
{
	std::vector<std::string> svec{ "kobe","joy","congratulation","mcgrady" };
	cout << "1-9 " << count_if(svec.cbegin(), svec.cend(), string_n(9, 1)) << endl;
	cout << "10- " << count_if(svec.cbegin(), svec.cend(), string_n(999, 10)) << endl;

}

练习14.40 重新编写10.3.2节的biggies函数,使其使用函数对象类替换其中的lambda表达式。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class biggies {
public:
	biggies(const std::size_t n) :len(n) {}
	bool operator()(const std::string &a,const std::string &b)
	{
		return a.size() < b.size();
	}
private:
	std::size_t len;
};
int main()
{
	vector<string> svec{ "kobe","paul","kangkang","zzz","kobe" };
	sort(svec.begin(), svec.end());
	auto iter = unique(svec.begin(), svec.end());
	svec.erase(iter, svec.end());
	stable_sort(svec.begin(), svec.end(), biggies(3));
	for (auto &i : svec) {
		cout << i << " ";
	}
}

练习14.41 你认为C++11新标准为什么要增加lambda?对于你自己来说,什么情况下会使用lambda,什么情况下使用类。

lambda用于小型程序中,出现次数极少,实现简单功能。

类用于大型程序中,频繁出现。


练习14.42 使用标准库函数对象及适配器定义一条表达式,令其

(a) 统计大于1024的值有多少个。

(b) 找到第一个不等于pooh的字符串。

(c) 将所有的值乘以2。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
	vector<int> ivec{ 7,77,7777,8888,9,1025 };
	cout << count_if(ivec.begin(), ivec.end(), bind2nd(greater<int>(), 1024)) << endl;
	
	vector<string> svec{ "hoop","hoop","mcgrady","dddd" };
	cout << *find_if(svec.begin(), svec.end(), bind2nd(not_equal_to<string>(), "hoop")) << endl;
	
	vector<int> ivec2 = ivec;
	transform(ivec.begin(), ivec.end(),ivec2.begin(), bind2nd(multiplies<int>(), 2));
	for (auto &i : ivec2) {
		cout << i << " ";
	}
}

练习14.43 使用标准库函数对象判断一个给定的int是否能被int容器中所有元素整除。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
	vector<int>ivec{ 2,4,6,8,10 };
	auto num = count_if(ivec.begin(), ivec.end(), bind2nd(modulus<int>(), 2));
	if (num == 0) {
		cout << "yes" << endl;
	}
	else {
		cout << "no" << endl;
	}
}

练习14.44 编写一个简单的桌面计算器使其能处理二元运算。

#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;
int add(int a, int b) { return a + b; }
struct divide {
	int operator()(int d, int d2) { return d / d2; }
};
int main()
{
	auto mod = [](int i, int j) {return i%j; };
	map<string, function<int(int, int)>> binops = {
		{"+",add},
		{"-",std::minus<int>()},
		{"/",divide()},
		{"*",[](int i, int j) {return i*j; }},
		{"%",mod}
	};
	cout <<binops["/"](9, 2.9)<<endl;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值