【第十六章】C++ Primer plus 的编程练习题

/***********************************
	2017年12月20日08:50:31
	Athor:xiyuan255
	Course:C++
	Contain:palindrome.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第一题练习题
		 【 参考 P729 】
*************************************/
// palindrome.cpp -- using palindrome check
#include <iostream>
#include <string>

bool isPalindrome(const std::string & str);

int main()
{
	using namespace std;
	string temp;
	cout << "Enter a number (quit to quit):\n";
	while (getline(cin, temp) && temp != "quit") {
		if (isPalindrome(temp)) 
			cout << "The number is palindrome!!\n";
		else
			cout << "The number not is palindrome!!\n";
		cout << "Enter next number (quit to quit):\n";
	}
	return 0;
}

/**
输出结果:
	Enter a number (quit to quit):
	oto
	The number is palindrome!!
	Enter next number (quit to quit):
	otto
	The number is palindrome!!
	Enter next number (quit to quit):
	ottsitto
	The number not is palindrome!!
	Enter next number (quit to quit):
	quit
*/

bool isPalindrome(const std::string & str)
{
#if 0
	// 方法一:
	for (int i = 0; i < str.size(); i++) {
		if (str[i] != str[str.size()-i-1])
			return false;
	}
#endif

#if 1
	// 方法二:
	for (auto it = str.begin(), ie = str.end(); it < ie; it++, ie--) {
		if (*it != *(ie-1)) 
			return false;
	}
#endif
	return true;
	
}

/***********************************
	2017年12月20日16:14:23
	Athor:xiyuan255
	Course:C++
	Contain:palindrome2.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第二题练习题
		 【 参考 P729 】
*************************************/
// palindrome.cpp -- using palindrome check
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>

using namespace std;

bool isPalindrome(const std::string & str);

int main()
{

	string temp;
	cout << "Enter a number (quit to quit):\n";
	while (getline(cin, temp) && temp != "quit") {
		if (isPalindrome(temp)) 
			cout << "The number is palindrome!!\n";
		else
			cout << "The number not is palindrome!!\n";
		cout << "Enter next number (quit to quit):\n";
	}
	return 0;
}

/**
输出结果:
	Enter a number (quit to quit):
	Madam, I'm Adam
	The number is palindrome!!
	Enter next number (quit to quit):
	Fnic ;;jsdh,
	The number not is palindrome!!
	Enter next number (quit to quit):
	quit
*/

bool isPalindrome(const std::string & str)
{
	std::string copy_str;
	for (auto it = str.begin(); it < str.end(); it++) {
		if ((*it >= 'a' && *it <= 'z')
			 ||(*it >= 'A' && *it <= 'Z')) {
			copy_str.push_back(*it); 
		}
	}
	//cout << "copy_str-0: " << copy_str << endl;
	transform(copy_str.begin(), copy_str.end(), 
		      copy_str.begin(), ::tolower); //调用std::tolower版本的该函数
	//cout << "copy_str-1: " << copy_str << endl;
	std::string temp(copy_str.rbegin(), copy_str.rend()); // 定义一个是copy_str对象倒序的对象
	//cout << "temp: " << temp << endl;

	return (copy_str == temp) ? true : false;
}

/***********************************
	2017年12月21日09:03:59
	Athor:xiyuan255
	Course:C++
	Contain:hangman2.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第三题练习题
		 【 参考 P729 】
*************************************/
// hangman2.cpp -- some string methods
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <vector>
#include <fstream>

int main()
{
	using std::cout;
	using std::cin;
	using std::tolower;
	using std::endl;
	using std::string;
	using std::vector;

	std::srand(time(0));
	vector<string> wordlist;
	std::ifstream fcin;
	fcin.open("wlist.txt");
	if (!fcin.is_open()) {
		cout << "open file fail!\n";
		exit(EXIT_FAILURE);
	}
	string temp;
	while (fcin >> temp) {
		wordlist.push_back(temp);
	}
	char play;
	cout << "Will you play a word game? <y/n>";
	cin >> play;
	play = tolower(play);
	while (play == 'y') {
		string target = wordlist[std::rand() % wordlist.size()];
		int length = target.length();
		string attempt(length, '-');
		string badchars;
		int guesses = 6;
		cout << "Guess my secret word. It has " << length
			 << " letters, and you guess\n"
		     << "one letter at a time. You get " << guesses
		     << " wrong guesses.\n";
		cout << "Your word: " << attempt << endl;
		while (guesses > 0 && attempt != target) {
			char letter;
			cout << "Guess a letter: ";
			cin >> letter;
			if (badchars.find(letter) != string::npos      // string::npos: npos值代表string对象所能
				|| attempt.find(letter) != string::npos) { // 容纳的最大值,一般是65535
				cout << "You already guessed that. Try again.\n";
				continue;
			}
			int loc = target.find(letter); // 如果target对象中存在字母letter,则返回该字母
			if (loc == string::npos) {     // 第一次出现的序号;如果不存在,则返回npos
				cout << "Oh, bad guess!\n";
				--guesses;
				badchars += letter;  // add to atring
			} else {
				cout << "Good guess!\n";
				attempt[loc] = letter;
				// check if letter appears again
				loc = target.find(letter, loc + 1);
				while (loc != string::npos) {
					attempt[loc] = letter;
					loc = target.find(letter, loc + 1);
				}
			}
			cout << "Your word: " << attempt << endl;
			if (attempt != target) {
				if (badchars.length() > 0)
					cout << "Bad choices: " << badchars << endl;
				cout << guesses << " bad guesses left\n";
			}
		}
		if (guesses > 0)
			cout << "That's right!\n";
		else
			cout << "Sorry, the word is " << target << ".\n";
		cout << "Will you play a word game? <y/n>";
		cin >> play;
		play = tolower(play);
	
	}

	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	Will you play a word game? <y/n>y
	Guess my secret word. It has 6 letters, and you guess
	one letter at a time. You get 6 wrong guesses.
	Your word: ------
	Guess a letter: a
	Good guess!
	Your word: -a-a--
	6 bad guesses left
	Guess a letter: g
	Good guess!
	Your word: ga-ag-
	6 bad guesses left
	Guess a letter: r
	Good guess!
	Your word: garag-
	6 bad guesses left
	Guess a letter: e
	Good guess!
	Your word: garage
	That's right!
	Will you play a word game? <y/n>n
	Bye.
*/

// wlist.txt
apiary beetle cereal danger ensign 
florid garage health insult jackal 
keeper loaner manage nonce  onset
plaid  quilt  remote stolid train
useful valid whence xenon yearn zippy


/***********************************
	2017年12月21日10:24:24
	Athor:xiyuan255
	Course:C++
	Contain:reduce.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第四题练习题
		 【 参考 P729 】
*************************************/
// reduce.cpp -- using STL methods 
#include <iostream>
#include <list>

int reduce(long ar[], int n);

int main()
{
	long arr[10] = { 1111, 2222, 4444, 6666, 2222,
	                 3333, 8888, 4444, 6666, 5555 };
	std::cout << "The unique before arr = \n";
	for (int i = 0; i < 10; i++) {
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;

	int len = reduce(arr, 10);
	//std::cout << len << std::endl;

	std::cout << "The unique after arr = \n";
	for (int i = 0; i < len; i++) {
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;

	return 0;
}

/**
输出结果:
	The unique before arr =
	1111 2222 4444 6666 2222 3333 8888 4444 6666 5555
	The unique after arr =
	1111 2222 3333 4444 5555 6666 8888
*/

int reduce(long ar[], int n)
{
	//std::vector<long> varr;
	std::list<long> larr;
	for (int i = 0; i < n; i++) {
		larr.push_back(ar[i]);
	}
	larr.sort();
	larr.unique();  // 把相邻的值相同的元素合并为一个元素

  //varr.sort();  // 为什么vector对象不提供sort()成员函数的原因?
	              // STL是对性能有苛求的库实现。通常容器在与外部算法合作
	              // 能够有最佳的性能表现,而且具备使用该算法的条件(通常
	              // 是合适的参数如迭代器,则该容器就不提供具体的成员函数
	              // 来实现这种算法。例如vector与Algorithms中的sort算法合
	              // 作,就可以提供最佳性能的排序操作,因此而不提供sort成
	              // 员函数。这样作对泛型设计有较大的好处。

                  // 而list则相反,因为list不支持随机存取迭代器,故不能使用
	              // Algorithms中的外部sort算法,因此,list的实现提供自已的
	              // sort成员函数以实现排序操作。 
	int count = 0;
	for (std::list<long>::iterator it = larr.begin(); it != larr.end(); it++) {
		ar[count++] = (*it);
	}
	// 方法一:
	// return larr.size();
	// 方法二:
	return count;
}

/***********************************
	2017年12月21日10:41:19
	Athor:xiyuan255
	Course:C++
	Contain:reduce2.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第五题练习题
		 【 参考 P729 】
*************************************/
// reduce2.cpp -- using STL methods 
#include <iostream>
#include <string>
#include <list>

template <class T>
int reduce(T ar[], int n);

int main()
{
	int len;

	long arr[10] = { 1111, 2222, 4444, 6666, 2222,
	                 3333, 8888, 4444, 6666, 5555 };
	std::cout << "The unique before arr = \n";
	for (int i = 0; i < 10; i++) {
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;
	len = reduce(arr, 10);
	std::cout << "The unique after arr = \n";
	for (int i = 0; i < len; i++) {
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;

	std::string str[8] = { "zhangsan", "wangwu", "zhaoliu", "zhangsan",
	                       "xiaoming", "lishi", "wangwu", "xiaohua" };
	std::cout << "The unique before arr = \n";
	for (int i = 0; i < 8; i++) {
		std::cout << str[i].c_str() << " ";  // 返回一个指向C风格的字符串指针,即char *
	}
	std::cout << std::endl;
	len = reduce(str, 8);
	std::cout << "The unique after arr = \n";
	for (int i = 0; i < len; i++) {
		std::cout << str[i].c_str() << " ";
	}
	std::cout << std::endl;

	return 0;
}

/**
输出结果:
	The unique before arr =
	1111 2222 4444 6666 2222 3333 8888 4444 6666 5555
	The unique after arr =
	1111 2222 3333 4444 5555 6666 8888
	The unique before arr =
	zhangsan wangwu zhaoliu zhangsan xiaoming lishi wangwu xiaohua
	The unique after arr =
	lishi wangwu xiaohua xiaoming zhangsan zhaoliu
*/

template <class T>
int reduce(T ar[], int n)
{
	std::list<T> larr;
	for (int i = 0; i < n; i++) {
		larr.push_back(ar[i]);
	}
	larr.sort();
	larr.unique();  // 把相邻的值相同的元素合并为一个元素

	int count = 0;
	for (std::list<T>::iterator it = larr.begin(); it != larr.end(); it++) {
		ar[count++] = (*it);
	}

	return count;
}

#ifndef __BANK2_H__
#define __BANK2_H__

// This queue will contain Customer items
class Customer
{
private:
	long arrive;        // arrive time for customer // 客户到达的时间
	int processtime;    // processing time for customer // 客户处理的时间
public:
	Customer() { arrive = processtime = 0; }
	void set(long when) {
		processtime = std::rand() % 3 + 1; // 处理时间随机为1 ~ 3分钟
		arrive = when;
	}
	long when() const { return arrive; }
	int ptime() const { return processtime; }
};

typedef Customer Item;

#endif /* __BANK2_H__ */

/***********************************
	2017年12月21日11:24:31
	Athor:xiyuan255
	Course:C++
	Contain:bank2.cpp
	         bank2.h
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第六题练习题
		 【 参考 P729 】
*************************************/
// bank2.cpp -- using the STL queue interface
#include <iostream>
#include <cstdlib>   // for rand() and srand()
#include <ctime>     // for time()
#include "bank2.h"
#include <queue> 

const int MIN_PER_HR = 60;

bool newCustomer(double x);  // is there a new customer?

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	using std::queue;
	using std::ios_base;
// setting things up
	std::srand(std::time(0));  // random initializing of rand()

	cout << "Case Study: Bank of Heather Automatic Teller\n";
	cout << "Enter maximum size of queue: ";
	int qs;
	cin >> qs;
	queue<Item> line;   // line queue holds up to qs people

	cout << "Enter the number of simulation hours: ";
	int hours;        // hours of simulation
	cin >> hours;
	// simulation will run 1 cycle per minute
	long cyclelimit = MIN_PER_HR * hours;  // # of cycles // 模拟多长时间(单位:分钟)

	cout << "Enter the average number of customer per hour: ";
	double perhour;      // average # of arrival per hour
	cin >> perhour;      // 每小时有多少个客户到达
	double min_per_cust; // average time between arrivals
	min_per_cust = MIN_PER_HR / perhour; //每个客户到达的平均时间(单位:分钟)

	Item temp;           // new customer data
	long turnaways = 0;  // truned away by full queue // 因队列已满,被拒绝的客户数目
	long customers = 0;  // joined the queue // 加入队列的客户数
	long served = 0;     // served during the simulation // 已经获得服务的客户数目
	long sum_line = 0;   // cumulative line length // 累积队列的长度(每分钟在队列中等待的客户数目
	     // 并不一定相同(因为存在出队和入队),即每分钟里队列的长度不相同,将每分钟里队列的长度
	     // 相加,即是sum_line的值。
	int wait_time = 0;   // time until autoteller is free // 等待前一个客户处理完成的等待时间
	long line_wait = 0;  // cumulative time in line  // 排队等候的累积时间

// running the simulation
	for (int cycle = 0; cycle < cyclelimit; cycle++) { // 程序没分钟循环一次,检查是否有客户到达
		if (newCustomer(min_per_cust)) {  // have newcomer
			if (line.size() >= qs)  // qs: 队列排队人数的最大值
				turnaways++;
			else {
				customers++;
				temp.set(cycle);    // cycle = time of arrival
				line.push(temp); // add newcomer to line
			}
		}
		if (wait_time <= 0 && line.size()) {
			temp = line.front();      // save queue front element
			line.pop();               // attend next customer
			wait_time = temp.ptime(); // for wait_time minutes
			line_wait += cycle - temp.when();
			served++;
		}
		if (wait_time > 0)
			wait_time--;
		sum_line += line.size(); // 正在排队的客户队列长度,不包括出队成员
	}

// reporting results
	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 << "sum_line: " << sum_line << endl;
		//cout << "line_wait: " << line_wait << endl;
		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;
}

// x = average time, in minutes, between customers
// return value is true if customer shows up this minute
bool newCustomer(double x)
{
	// stdlib.h头文件中有宏 #define RAND_MAX 0x7fff; rand()产生一个0到0x7ffff
	// 即0到32767之间的随机数,( rand() / RAND_MAX )就等于一个0到1之间的小数了,
	// 因为rand()最大是32767最小是0, 再除以32767就是一个0到1之间的小数, 再乘以
	// x就是一个0到x之间的小数了.
	//double temp = std::rand() * x / RAND_MAX;
	//std::cout << "randtime: " << temp << std::endl;
	//return temp < 1;
	//std::cout << "x: " << x << std::endl;
	return (std::rand() * x / RAND_MAX < 1); // 该语句用来模拟是否有新客户到达,如果
	                        // std::rand() * x / RAND_MAX < 1 代表有新客户到达了。
	// 本程序中,在第一种输出结果时,x=60/15=4;说明std::rand() * x / RAND_MAX的值将
	// 0到4之间的小数,具体的说,平均每4次就会出现一次小于1的情况。
	
}
/**
输出结果1:
	Case Study: Bank of Heather Automatic Teller
	Enter maximum size of queue: 10
	Enter the number of simulation hours: 100
	Enter the average number of customer per hour: 15
	customers accepted: 1502
	  customers served: 1502
			 turnaways: 0
	average queue size: 0.17
	average wait time: 0.69 minutes
	Done!

输出结果2:
	Case Study: Bank of Heather Automatic Teller
	Enter maximum size of queue: 20
	Enter the number of simulation hours: 100
	Enter the average number of customer per hour: 30
	customers accepted: 2953
	  customers served: 2934
			 turnaways: 30
	average queue size: 9.28
	average wait time: 18.85 minutes
	Done!

输出结果3:
	Case Study: Bank of Heather Automatic Teller
	Enter maximum size of queue: 20
	Enter the number of simulation hours: 100
	Enter the average number of customer per hour: 30
	customers accepted: 2963
	  customers served: 2947
			 turnaways: 65
	average queue size: 9.82
	average wait time: 19.90 minutes
	Done!
*/

/***********************************
	2017年12月21日13:16:01
	Athor:xiyuan255
	Course:C++
	Contain:pe16-7.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第七题练习题
		 【 参考 P729 】
	总结:1.List封装了链表,Vector封装了数组, list和vector得最主要的区别:
		    (1) vector使用连续内存存储的,他支持[]运算符;Vector对于随机访问
			    的速度很快,但对于插入尤其是在头部插入元素速度很慢(因为要移动
			    大量元素),但尾部插入速度很快。
		    (2) list是以链表形式实现的,不支持[]。List对于随机访问速度慢得多,
			    因为要遍历整个链表,但是对于插入就快的多了,不需要拷贝和移动
			    数据。只要改变指针指向即可。
		    另外对于新添加的元素,Vector有一套算法,而List可以任意加入。
		  2.Map,Set属于标准关联容器,使用了非常高效的平衡检索二叉树:红黑树,
		    他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,
		    而直接替换指向节点的指针即可。
		    (1) Set和Vector的区别在于Set不包含重复的数据。
		    (2) Set和Map的区别在于Set只含有Key,而Map有一个Key和Key所对应的
			    Value两个元素。
		    (3) Map和Hash_Map的区别是Hash_Map使用了Hash算法来加快查找过程,
			    但是需要更多的内存来存放这些Hash桶元素,因此可以算得上是采用
			    空间来换取时间策略。
*************************************/
// pe16-7.cpp -- using STL vector template class
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>

using std::endl;
using std::cout;
using std::vector;

vector<int> lotto(int tot_num, int num);

int main()
{
	std::srand(time(0));
	vector<int> winners;
	winners = lotto(51, 6);
	vector<int>::iterator it;
	cout << "The 6 numbers of winner: ";
	for (it = winners.begin(); it != winners.end(); it++) {
		cout << (*it) << " ";
	}
	cout << endl;
	return 0;
}

/**
输出结果:
	total random numbers:
	 16  37  34  38  32  17  18  10
	 29  49  13  45  42  30  22  47
	 14   8   1  23  39  46   7  27
	  6  19  43  12   3  51  35  44
	 20  26  25   4  40  11  33  21
	 31  15   5   9  48  41  50  36
	  2  28  24 , size:51
	The 6 numbers of winner: 51 3 22 39 48 35
*/

vector<int> lotto(int tot_num, int num)
{
	std::vector<int> total;
	for (int i = 1; i <= tot_num; i++)
		total.push_back(i);
	random_shuffle(total.begin(), total.end());
	cout << "total random numbers: \n";
	for (int i = 0; i < tot_num; i++) {
		cout.width(3);
		cout << total[i] << " ";
		if (i % 8 == 7)
			cout << endl;
	}
	cout << ", size:" << total.size() << endl;

	std::vector<int> winner;
	for (int i = 0; i < num; i++) {
		winner.push_back(total[rand()%tot_num]);
	}
	return winner;
}

/***********************************
	2017年12月21日14:22:33
	Athor:xiyuan255
	Course:C++
	Contain:pe16-8.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第八题练习题
		 【 参考 P729 】
*************************************/
// pe16-8.cpp -- using
#include <iostream>
#include <string>
#include <list>
#include <set>
#include <algorithm>

void show(const std::string & str)
{
	std::cout << str << " ";
}

int main()
{
	std::list<std::string> Mat;
	std::list<std::string> Pat;
	
	std::string temp;
	std::cout << "Enter Mat friend name (quit to quit): \n";
	while (getline(std::cin, temp) && temp != "quit") {
		Mat.push_back(temp);
	}
	Mat.sort();

	std::cout << "Enter Pat friend name (quit to quit): \n";
	while (getline(std::cin, temp) && temp != "quit") {
		Pat.push_back(temp);
	}
	Pat.sort();

	std::cout << "Mat friend have: \n";
	for_each(Mat.begin(), Mat.end(), show);
	std::cout << std::endl;

	std::cout << "Pat friend have: \n";
	for_each(Pat.begin(), Pat.end(), show);
	std::cout << std::endl;

	// 方法一:
#if 0
	std::set<std::string> Merge;
	std::list<std::string>::iterator it;
	for (it = Mat.begin(); it != Mat.end(); it++)
		Merge.insert(*it);
	for (it = Pat.begin(); it != Pat.end(); it++)
		Merge.insert(*it);
#endif

	// 方法二:
	std::list<std::string> Merge;
	Merge = Mat;
	Merge.merge(Pat);
	Merge.unique();

	std::cout << "Merge friend have: \n";
	for_each(Merge.begin(), Merge.end(), show);
	std::cout << std::endl;

	return 0;
}

/**
输出结果:
	Enter Mat friend name (quit to quit):
	zhangsan
	lishi
	wangwu
	zhaoliu
	xiaoming
	quit
	Enter Pat friend name (quit to quit):
	lishi
	xiaohua
	lilei
	zhaoliu
	tianmo
	xiaoqing
	quit
	Mat friend have:
	lishi wangwu xiaoming zhangsan zhaoliu
	Pat friend have:
	lilei lishi tianmo xiaohua xiaoqing zhaoliu
	Merge friend have:
	lilei lishi tianmo wangwu xiaohua xiaoming xiaoqing zhangsan zhaoliu
*/

/***********************************
	2017年12月21日16:11:57
	Athor:xiyuan255
	Course:C++
	Contain:pe16-9.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第九题练习题
		 【 参考 P729 】
	总结:
		1.clock()返回从“开启这个程序进程”到“程序中调用clock()函数”
		  时之间的CPU时钟计时单元(clock tick)数;
		2.time(&temp)返回从CUT(Coordinated Universal Time)时间1970年
		  1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。
		  总之,用time_t计时才是人们正常意识上的秒数,而clock_t计时所
		  表示的是占用CPU的时钟单元。
		3.STL的vector(内核是数组)和list(内核的链表)的区别:
		  (1) vector的排序能力比list要快得多,且vector只有结尾插入元素
		      才比较快,提供了push_back()方法;
		  (2) list的排序能力比list要慢得多,但list的插入能力要比vector
		      要快的多;且可以在不同位置进行插入。
*************************************/
// pe16-9.cpp -- using List and Vector
#include <iostream>
#include <vector>
#include <list>
#include <ctime>
#include <algorithm>

const int NUM = 1000000;
using namespace std;

int main()
{
	int i;
	srand(time(0));
	vector<int> vi0;
	for (i = 0; i < NUM; i++)
		vi0.push_back(rand());

	vector<int> vi = vi0;
	list<int> li;
	for (i = 0; i < vi0.size(); i++)
		li.push_back(vi0[i]);

	clock_t start, end;
	start = clock();  // return CPU clock tick  // uint:ms
	sort(vi.begin(), vi.end());
	end = clock();  
	cout << "vector<int> sort time = " << (double)(end - start) / CLOCKS_PER_SEC << " secound.\n";

	start = clock();  // return CPU clock tick 
	li.sort();
	end = clock();  
	cout << "list<int> sort time = " << (double)(end - start) / CLOCKS_PER_SEC << " secound.\n";

#if 0 // 方法一:
	li.clear();
	for (i = 0; i < vi0.size(); i++)
		li.push_back(vi0[i]);
#endif

	// 方法二:
	copy(vi0.begin(), vi0.end(), li.begin());

	start = clock();  // return CPU clock tick 
	list<int>::iterator it;
	//cout << "vi.size(): " << vi.size() << ", li.size(): " << li.size() << endl;
	for (it = li.begin(), i = 0; it != li.end(); it++, i++)
		vi[i] = *it;
	sort(vi.begin(), vi.end());
	copy(vi.begin(), vi.end(), li.begin());
	end = clock();  
	cout << "li copy to vi after sort time = " // CLOCKS_PER_SEC: 1000
		 << (double)(end - start) / CLOCKS_PER_SEC << " secound.\n";

	return 0;
}

/**
输出结果:
	vector<int> sort time = 1.663 secound.
	list<int> sort time = 121.452 secound.
	li copy to vi after sort time = 4.3 secound.
*/

/***********************************
	2017年12月22日09:54:37
	Athor:xiyuan255
	Course:C++
	Contain:vect4.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第十题练习题
		 【 参考 P729 】
*************************************/
// vect4.cpp -- using STL functions 使用智能指针
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <memory>

struct Review {
	std::string title;
	int rating;
	float price;
};

bool operator<(const std::shared_ptr<Review> & r1, const std::shared_ptr<Review> & r2);
bool compRating(const std::shared_ptr<Review> & r1, const std::shared_ptr<Review> & r2);
bool compPrice(const std::shared_ptr<Review> & r1, const std::shared_ptr<Review> & r2);
bool fillReview(Review & rr);
void showReview(const std::shared_ptr<Review> & rr);

int main()
{
	using namespace std;

	vector< shared_ptr<Review> > books;
	Review temp;
	while (fillReview(temp)) {
		shared_ptr<Review> sptr(new Review);
		sptr->title = temp.title;
		sptr->rating = temp.rating;
		sptr->price = temp.price;
		books.push_back(sptr); 
	}
	if (books.size() > 0) {
		bool flag = true;
		cout << "1.按原始顺序显式:2.按字母表顺序显式:3.按评级升序显示:\n"
			 << "4.按评级降序显示:5.按价格升序显示:  6.按价格降序显式:\n"
			 << "7.退出显式:\n";
		int input;
		while (flag) 
		{
			cout << "输入要显式的方式:";
			cin >> input;
			switch (input) {
				case 1: 
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 2:
					sort(books.begin(), books.end());
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 3:
					sort(books.begin(), books.end(), compRating);
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 4:
					sort(books.rbegin(), books.rend(), compRating);
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 5:
					sort(books.begin(), books.end(), compPrice);
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 6:
					sort(books.rbegin(), books.rend(), compPrice);
					cout << "Rating\tPrice\tBooks\n";
					for_each(books.begin(), books.end(), showReview);
					break;
				case 7:
					flag = false;
					break;
			}
		}
	} else
		cout << "No entries. ";
	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	Enter book title (quit to quit): The Cat Who Can Teach You Weight Los
	Enter book rating: 8
	Enter book price: 45.5
	Enter book title (quit to quit): The Dogs of Dharma
	Enter book rating: 6
	Enter book price: 60
	Enter book title (quit to quit): The Wimps of Wonk
	Enter book rating: 3
	Enter book price: 102.5
	Enter book title (quit to quit): Farewell and Delete
	Enter book rating: 7
	Enter book price: 83
	Enter book title (quit to quit): quit
	1.按原始顺序显式:2.按字母表顺序显式:3.按评级升序显示:
	4.按评级降序显示:5.按价格升序显示:  6.按价格降序显式:
	7.退出显式:
	输入要显式的方式:1
	Rating  Price   Books
	8       45.5    The Cat Who Can Teach You Weight Loss
	6       60      The Dogs of Dharma
	3       102.5   The Wimps of Wonk
	7       83      Farewell and Delete
	输入要显式的方式:2
	Rating  Price   Books
	7       83      Farewell and Delete
	8       45.5    The Cat Who Can Teach You Weight Loss
	6       60      The Dogs of Dharma
	3       102.5   The Wimps of Wonk
	输入要显式的方式:3
	Rating  Price   Books
	3       102.5   The Wimps of Wonk
	6       60      The Dogs of Dharma
	7       83      Farewell and Delete
	8       45.5    The Cat Who Can Teach You Weight Loss
	输入要显式的方式:4
	Rating  Price   Books
	8       45.5    The Cat Who Can Teach You Weight Loss
	7       83      Farewell and Delete
	6       60      The Dogs of Dharma
	3       102.5   The Wimps of Wonk
	输入要显式的方式:5
	Rating  Price   Books
	8       45.5    The Cat Who Can Teach You Weight Loss
	6       60      The Dogs of Dharma
	7       83      Farewell and Delete
	3       102.5   The Wimps of Wonk
	输入要显式的方式:6
	Rating  Price   Books
	3       102.5   The Wimps of Wonk
	7       83      Farewell and Delete
	6       60      The Dogs of Dharma
	8       45.5    The Cat Who Can Teach You Weight Loss
	输入要显式的方式:7
	Bye.
*/

bool operator<(const std::shared_ptr<Review> & r1, const std::shared_ptr<Review> & r2)
{ // 按升序排列,则如果第一个参数小于第二个参数属于正确的,所以应返回true
	if (r1->title < r2->title)
		return true;
	else if (r1->title == r2->title && r1->rating < r2->rating)
		return true;
	else
		return false;
}

bool compRating(const std::shared_ptr<Review> & r1, const std::shared_ptr<Review> & r2)
{
	std::cout << "r1->rating: " << r1->rating << " r2->rating: " << r2->rating << std::endl;
	if (r1->rating < r2->rating)
		return true;
	else
		return false;
}

bool compPrice(const std::shared_ptr<Review> & r1, const std::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: ";
	std::cin >> rr.price;
	if (!std::cin)
		return false;
	// get rid of rest of input line
	while (std::cin.get() != '\n')
		continue;

	return true;
}

void showReview(const std::shared_ptr<Review> & rr)
{
	std::cout << rr->rating << "\t" << rr->price << "\t" << rr->title << std::endl;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值