/***********************************
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;
}