c++ Primer Plus(第六版)第十六章习题,写代码之路

c++ Primer Plus(习题16.1)

//让用户输入回文的单词,就是那种倒着读和顺着读一样意思的
//实现这个功能有很多方法,用了一种简单的方法
#include<iostream>
#include<string>
using std::string;
using std ::cout;
using std::cin;
using std::getline;
using std::endl;
bool Isplalindrome(const string &s);
int main()
{

	string p;
	cout << "Enter a plalindrome word: ";
	while (getline(cin, p)&&p != "q")
	{

		if (Isplalindrome(p))
			cout << "Yes, " << p << " is a plalindrome word!\n";
		else
			cout << "Sorry,is not a plalindrome word!\n";
		cout << "Think about another word: (q to exit)";
		//getline(cin,p);
	}
	cout << "Bye!\n";
}
bool Isplalindrome(const string &s)
{
	string temp = s;		//string temp(words.rbegin(), words.rend());
	int j = s.size();		//用上面的反转迭代器更简单
	int i=0;
	for (; i <j; i++)
		temp[i]=s[s.size() - i-1];			//因为string索引的问题,这里要减一个
	temp[i] = '\0';
	if (temp==s)
		return true;
	return false;
}
c++ Primer Plus(习题16.2)

//让用户输入回文的单词,就是那种倒着读和顺着读一样意思的
//前面一道题目的升级版,客户要求的
//考虑输入句子,大小写等复杂的情况
//感觉思路不太好,结果没什么问题,就是饶了一点
#include<iostream>
#include<string>
#include<cctype>				//处理大小写
using std::string;
using std::cout;
using std::cin;
using std::getline;
using std::endl;
bool Isplalindrome(const string &s);
int main()
{

	string p;
	cout << "Enter a plalindrome word: ";
	while (getline(cin, p) && p != "q")
	{

		if (Isplalindrome(p))
			cout << "Yes, " << p << " is a plalindrome.\n";
		else
			cout << "Sorry,is not a plalindrome.\n";
		cout << "Think about another word: (q to exit)";
		//getline(cin,p);
	}
	cout << "Bye!\n";
}
bool Isplalindrome(const string &s)
{
	string temp;		//这个用于存储去掉大写,和非字母字符的string类,反转后的类			
	int i = 0;
	int j = s.size() - 1;
	for (; j>=0;j--)
	{
		if (isalpha(s[j]))					//判断字符是否是字母	
		{								//处理大小写字符
			temp.push_back(tolower(s[j]));	//还是这种方法好一点
			i++;
		}
}
	//temp[i] = '\0'; string的结尾标记没有规定是'\0'这种方法不可行
	string tem(temp.rbegin(), temp.rend());
	if (temp == tem)
		return true;
	return false;
}
c++ Primer Plus(习题16.3)

//这题是修改程序清单16.3,改成从文件中读取单词,而不是从数组中 
//书上已经有解决方案了,照着就ok.
#include <iostream>  
#include <fstream>  
#include <vector>  
#include <string>  
#include <cstdlib>  
#include <ctime>  
#include <cctype>  

const int NUM = 26;
void Readword();
std::vector<std::string> input;			//全局变量省的传递参数了
int main()
{
	std::srand(std::time(0)); 
	char play;
	std::cout << "Will you play a word game? <Y/N> ";
	std::cin >> play;
	play = std::tolower(play);
	Readword();
	while (play=='y')
	{
		std::string target= input[std::rand() % NUM];
		int length = target.length();
		std::string attempt(length, '-');
		std::string badchars;
		int guesses = 6;
		std::cout << "Guess my secret word. It has " << length 
			<< " letters, and you guess\n" << "one letter at a time. You get " 
			<< guesses << " wrong guesses.\n";
		std::cout << "Your word: " << attempt << std::endl;
		while (guesses > 0 && attempt != target)
		{
			char letter;
			std::cout << "Guess a letter: ";
			std::cin >> letter;
			if ((badchars.find(letter) != std::string::npos) //nops是string中的最大存储字符数
				|| (attempt.find(letter)!= std::string::npos))
			{
				std::cout << "You already guessed that. Try again.\n";
				continue;
			}
			int loc = target.find(letter);			//记录找到字符的位置
			if (loc == std::string::npos)
			{
				std::cout << "Oh, bad guess!\n";
				--guesses;
				badchars +=letter;					//记录到错误的那里
			}
			else
			{
				std::cout << "Good guess!\n";
				attempt[loc] =letter;		//显示猜对的字符
				loc = target.find(letter, loc + 1);
				while (loc != std::string::npos)	//显示这个单词后面相同的字符
				{
					attempt[loc] =letter;
					loc = target.find(letter, loc + 1);
				}
			}
			std::cout << "Your word: " << attempt << std::endl;
			if (attempt != target)
			{
				if (badchars.length() > 0)
					std::cout << "Bad choices: " << badchars << std::endl;
				std::cout << guesses << " bad guesses left\n";
			}
		}
		if (guesses > 0)
			std::cout << "That's right\n";
		else
			std::cout << "Sorry, the word is " << target << ".\n";
		std::cout << "Will you play another? <Y/N> ";
		std::cin >> play;
		play = tolower(play);
	}
	std::cout << "Bye!\n";
	return 0;
}
void Readword()
{
	std::ifstream fin;
	fin.open("data.txt");
	if(!fin.is_open())
	{
		std::cout << "Open file data.txt error!\n";
		exit(EXIT_FAILURE);
	}
	std::string s;				//存储读取的单词
	while (!fin.eof())
	{
		fin>>s;
		input.push_back(s);			//动态增加input的成员数量
	}
	fin.close();
}
c++ Primer Plus(习题16.4)

//这题是熟悉stl特性,编写一个函数接受一个数组和元数个数
//对数组进行排序,删除重复的值,并返回最终的元素个数
//考虑到压缩元素,可以使用list模板类,书上的unique()函数也是一种提示
#include<iostream>
#include<list>							//list模板,双向链表
#include<algorithm>						//迭代器
std::list<long>f;
int reduce(long ar[], int i);
void outlong(long n) { std::cout << n << " "; }
int main()
{
	using std::cout;
	long test[12] = { 40,51,57,89,87,85,40,40,51,64,52,0 };
	int result;
	result = reduce(test, 12);
	cout << "Source array: \n";
	for (long x : test)					//基于范围的for循环
			cout << x << " ";
	cout << "\nThe mount: " << 12;
	std::cout << "\nAfter sort and remove, the number is "<<result<<std::endl;
	cout << "After that: \n";
	std::for_each(f.begin(), f.end(), outlong);
	std::cout << "Bye!\n";
	return 0;
}
int reduce(long ar[], int i)			//使用迭代器将非常其简单,不过要会choose
{
	f.insert(f.begin(),ar, ar + i);
	f.sort();						//排序
	f.unique();						//压缩相同的元素
	return f.size();
}
c++ Primer Plus(习题16.5)

//这题是上一题的泛型,可以不依赖于特定的数组类型
//这就是迭代器的终极奥义,独立于类型
#include<iostream>
#include<algorithm>
#include<string>
#include<list>	
template<class T>
int reduce(T ar[], int n);
template<class T>
void outlong(T n) { std::cout << n << " "; }
int main()
{
	using std::cout;
	cout << "Test a function,accept a type array and longth,return after reduce same elemet"
		"mount." << std::endl;

	long test[12] = { 40,51,57,89,87,85,40,40,51,64,52,0 };
	int result;
	result = reduce(test, 12);
	cout << result<<std::endl;
std::string tests[5] = { "i","m a C","+","+","student." };
	result = reduce(tests, 5);
	cout << result<<std::endl;
}
template<class T>
int reduce(T ar[], int n)
{
	std::list<T>f;
	f.insert(f.begin(), ar, ar + n);
	f.sort();
	f.unique();
	std::cout << "After reduce and sort:\n";
	std::for_each(f.begin(), f.end(), outlong<T>);
	std::cout << std::endl;
	return f.size();
	
}
c++ Primer Plus(习题16.6)

//改写程序清单12.12就是那个排队买东西的,在c primer中也有
//使用stl queue 有高级的函数辅助加上一些queue 的stl功能,
//很容易实现,毕竟是标准的,我们自己做的功能没那么强大
#include <iostream>  
#include <cstdlib>  
#include <ctime>  
#include <queue>
class Customer
{
private:
	long arrive;
	int processtime;
public:
	Customer() { arrive = processtime = 0; }
	void set(long when) 
	{
		processtime = std::rand() % 3 + 1;
		arrive = when;
	}
	long when()const { return arrive; }
	int ptime()const { return processtime; }
};
typedef Customer Item;
const int MIN_PER_HR = 60;
bool newcustomer(double x);
int main()
{
	using namespace std;
	srand(time(0));
	cout << "Case Study: Bank of Heather Automatic Teller\n";
	cout << "Enter maximum size of queue: ";		//最大的排队人数
	int qs;
	cin >> qs;
	queue <Item>line;								//queue本人没看到指定队列数的构造函数
	cout << "Enter the number of simulation hours: ";	//测试的时间
	int hours;
	cin >> hours;
	long cyclelimit = MIN_PER_HR*hours;
	cout << "Enter the average number of cunstomers per hour: ";	//每小时的额客户数
	double perhour;
	cin >> perhour;
	double min_per_cust;
	min_per_cust = MIN_PER_HR / perhour;				//记录总的分钟数
	Item temp;
	long turnaways = 0;									//拒绝人数
	long customers = 0;									//来的人数
	long served = 0;									//服务人数
	long sum_line = 0;									//队列的长度
	int wait_time = 0;									//取款机空闲的等待时间	
	long line_wait = 0;									//队列的总等待时间
	for (long cycle = 0; cycle < cyclelimit; cycle++)
	{
		if (newcustomer(min_per_cust))
		{
			if (line.size()==qs)						//检查队列的长度是否等于最大排队人数
				turnaways++;
			else 
			{
				customers++;
				temp.set(cycle);
				line.push(temp);							//enqueue和push同样的方法
			}
		}
		if (wait_time <= 0 && !line.empty())
		{
			line.pop();								//弹出,不需要item参数
			wait_time = temp.ptime();	
			line_wait += cycle - temp.when();
			served++;
		}
		if (wait_time > 0)
			wait_time--;
		sum_line += (line.size()) / 2;
	}
	if (customers > 0) {
		cout << "customers accepted: " << customers << endl;
		cout << "  customers served: " << served << endl;
		cout << "        turnaways: " << turnaways << endl;
		cout << "average queue size: ";
		cout.precision(2);
		cout.setf(ios_base::fixed, ios_base::floatfield);
		cout << (double)sum_line / cyclelimit << endl;
		cout << "average wait time: " << (double)line_wait / served << " minutes\n";
	}
	else
		cout << "No customers!\n";
	cout << "Done!\n";
	return 0;
}
bool newcustomer(double x)
{
	return (rand()*x / RAND_MAX < 1);
}
c++ Primer Plus(习题16.7)

//一个彩票卡的游戏,本人没听说过,
//也是设计一个函数,要求使用vector容器
//额,程序每次运行获取的值都一样,这要是真是中奖的程序,等着骂吧
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> Lotto(int count, int ccount);	//返回一个包含vector
										//从第一个参数随机选择第二个参数数量值的对象
int main()
{
	cout << "This is a Lottery card Test program."
		"To test a funtion Lotto: \n";
	vector<int>winners;
	int numb, times;
	cout << "Enter a draw range: ";
	cin >> numb;
	cout << "How many times your draw less than: ";
	cin >> times;
	winners = Lotto(numb,times);
	cout<< "The winners Lottery card winning number is:\n";
	for (auto m = winners.begin(); m != winners.end(); m++)    //用迭代器的方式输出容器对象的值
	{
		cout<< *m << endl;
	}
	cout << "Good lucky!\n";
	cout << "Test complete!\n";
	return 0;
}
vector<int> Lotto(int count, int ccount)
{
	vector<int>pvalue(count);				//用来记录可能值,用了指定元素个数的f方法
	vector<int>value;						//用于返回
	for (int i = 0; i < count; i++)
		pvalue[i] = i + 1;
	for (int i = 0; i < ccount; i++)				//打乱ccount指定的次数,每次取第一个值存入数组
	{
		random_shuffle(pvalue.begin(), pvalue.end());
		value.push_back(pvalue[0]);
	}
	return value;
}
c++ Primer Plus(习题16.8)

//两个朋友认识的人的名字,用容器存储
//合并两个人中相同的元素,保存到第三个容器中
//考虑采用set关联容器
#include<iostream>
#include<string>
#include<set>
#include<algorithm>
#include<iterator>				//迭代器的头文件
int main()
{
	using namespace std;
	ostream_iterator<string, char>out(cout, " ");			//输出迭代器
	string Mat[5] = { "Joly","Jack","Zoe","Jay,Zou","X" };	//直接用这个来初始化了
	string Pat[4] = { "Joly","Emil","X","Lai Mei" };
	set<string>A(Mat, Mat + 5);			//第一个容器,set容器自动排序,大家都知道
	cout << "Mat's friends:\n";
	copy(A.begin(), A.end(), out);		//STL函数,复制到输出流迭代器
	cout << endl;						//说白了,就是显示容器内容
	set<string>B(Pat, Pat + 4);
	cout << "Pat's friends:\n";
	copy(B.begin(), B.end(), out);
	cout << endl;
	set<string>C;
	set_union(A.begin(), A.end(), B.begin(), B.end(), 
		insert_iterator<set<string>>(C, C.begin()));		//AB集合,用了一个插入迭代器
	cout << "Friends they have:\n";
	copy(C.begin(), C.end(), out);
	cout << endl;
	return 0;
}
c++ Primer Plus(习题16.9)

//这是作者的一个假设,在我们生活中也有很多这样的假设
//他的思路是在数组中排序元素,然后复制到链表中(因为链表排序是在很麻烦)
//借用中间容器实现排序功能的实现,下面就是测试时间
#include<iostream>
#include<vector>
#include<list>
#include<algorithm>
#include<iterator>
#include<ctime>					//提供时间函数
const int Num=1000000;			//这个要足够大
void outint(int n) { std::cout << n << " "; }
int main()
{
	using namespace std;
	vector<int>vi0(Num);				//指定个数的初始化
	for (int i=0; i < Num; i++)
		vi0[i]=rand()%100 + 1;
	cout << "Hello,this program set to accumulate time between STL sort method "
		"for vector object,and list sort methods.\n";
	cout << "Number of elements is " << Num << endl;
	vector<int>vi;
	vi = vi0;										//调用vector的赋值运算符
	list<int>li(Num);								//指定个数的初始化
	copy(vi0.begin(), vi0.end(), li.begin());		//不同容器之间的数据复制
	//计算三种方法的时间,方法一,使用使用STL算法对vi进行排序
	clock_t start = clock();
	sort(vi.begin(), vi.end());
	clock_t end = clock();
	cout << "Frist method,using STL sort time " << (double)(end - start) / CLOCKS_PER_SEC << " s.\n";
	//第二次测试
	clock_t start_2= clock();
	li.sort();
	clock_t end_2= clock();
	cout << "Second method,using list sort time " << (double)(end_2 - start_2) / CLOCKS_PER_SEC << " s.\n";
	//第三次测试
	copy(vi0.begin(), vi0.end(), li.begin());		//重置li链表
	clock_t start_3 = clock();
	copy(li.begin(), li.end(), vi.begin());			//把list的值复制到vi容器
	sort(vi.begin(), vi.end());						//排序
	copy(vi.begin(), vi.end(), li.begin());
	clock_t end_3 = clock();
	cout << "Third method,using other sort time " << (double)(end_3 - start_3) / CLOCKS_PER_SEC << " s.\n";
	cout << "Now,you can see,\nwhen list container count become big,sortting them is too long."
		"\nSo,make right choice to compelete a function.\n";
	return 0;
}

c++ Primer Plus(习题16.10)

//又是修改程序的题目,这最后的习题涉及到智能指针
//然后我们要做的就是满足客户的额要求,升级我们的程序
//不知道加了哪个头文件导致cout不明确
//这题的思路是书上的方案,如果自己做的话可以想排序字符串那样
//只使用指针数组排序,对指针进行排序
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>				//提供一些STL方法
#include<memory>				//智能指针头文件
struct Review					//结构是一种默认为公有的类
{
	std::string title;
	int rating;
	double price;				//增加的成员,书价格
};
using namespace std;		//书上也是按引用传递指针的意义非凡,其实不还是指针,没设呢么区别
bool operator<(shared_ptr<Review>r1, shared_ptr<Review>r2);//按字母排序的
bool woreThan(shared_ptr<Review>r1, shared_ptr<Review>r2);	//评分排序的
bool expensivethen(shared_ptr<Review>r1, shared_ptr<Review>r2);	//价格排序的
bool FillReview(Review*rr);
void ShowReview(shared_ptr<Review>rr);			//有点特别,书上的用法
void Showmenu();
int main()
{
	Review temp;
	vector<shared_ptr<Review>>pr;
	while (FillReview(&temp))
		pr.push_back(shared_ptr<Review>(new Review(temp)));
	//没认真看书,这个初始化想了好久好久
	vector<shared_ptr<Review>>tem(pr);		//用vector自带的初始化,是一个按名称排序的vector
	sort(tem.begin(), tem.end());			//创建按指针排序的<运算符,全排序
	//按评分排序的
	vector<shared_ptr<Review>>tem2(pr);
	sort(tem2.begin(), tem2.end(), woreThan);		//调用函数进行排序,完整弱排序
	//按价格排序
	vector<shared_ptr<Review>>tem3(pr);
	sort(tem3.begin(), tem3.end(), expensivethen);
	if (pr.size() > 0)
	{
		std::cout<< "Thank you,You entered the following "
			<< pr.size() << " ratings.\n";
		Showmenu();
		char choose;
		cin >> choose;
		while (choose != 'q')
		{
			switch (choose)
			{					//天真的我竟然在后面加&这个
			case 'a':for_each(pr.begin(),pr.end(), ShowReview); break;
			case'b': for_each(tem.begin(),tem.end(), ShowReview); break;
			case'c':for_each(tem2.begin(), tem2.end(), ShowReview); break;
			case'd':for_each(tem2.rbegin(), tem2.rend(), ShowReview); break;
			case 'e':for_each(tem3.begin(), tem3.end(), ShowReview); break;
			case'f':for_each(tem3.rbegin(), tem3.rend(), ShowReview); break;
			case 'q':break;
			default: std::cout << "Error choose,choose again:\n";
				break;
			}
			Showmenu();
			cin >> choose;
		}
	}
	else
		std::cout << "No data!\n";
	std::cout << "Bye!\n";
	return 0;
}
bool operator<(shared_ptr<Review>r1, shared_ptr<Review>r2)		
{
	if (r1->title < r2->title)
		return true;
	else if (r1->title == r2->title&&r1->rating < r2->rating)
		return true;		//这里不想太麻烦,就选择评分为优先排序项目
	else
		return false;
}
bool woreThan(shared_ptr<Review>r1, shared_ptr<Review>r2)  //按评分升序
{
	if (r1->rating<r2->rating)
		return true;
	else
		return false;
}
bool expensivethen(shared_ptr<Review>r1, shared_ptr<Review>r2) //按价格升序
{
	if (r1->price < r2->price)
		return true;
	else
		return false;
}
bool FillReview(Review*rr)
{
	std::cout << "Enter book title(quit to quit): ";
	std::getline(std::cin, rr->title);
	if (rr->title == "quit")
		return false;
	std::cout << "Enter book rating: ";
	std::cin >> rr->rating;
	if (!std::cin)
		return false;					//检查错误输入
	std::cout << "Enter book price(unit:yuan): ";
	std::cin >> rr->price;
	if (!std::cin)
		return false;
	while (std::cin.get() != '\n')
		continue;
	return true;
}
void ShowReview(shared_ptr<Review>rr)
{
	std::cout << rr->title<< "\t\t\t\t\t" << rr->rating << "\t $ " << rr->price 
		<< "\tyuan.\n";
}
void Showmenu()
{
	std::cout << "Make a choose to display them: \n"
		"a) Display by original order.            b) Display by alphabetic order.\n"
		"c) Display by rating ascending order.     d) Display by rating descending order.\n"
		"e) Display by price ascending order.      f) Display by price descending order.\n"
		"q) quit.\n";
}











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值