发现答案资源不全,因此贴出自己的解答,都为STL应用基础题,如有谬误,还请不吝赐教。


第一题

要求:回文字符串判断(假定字符串中没有大小写、空格、标点符号等问题)

解答:

#include<iostream>
#include<string>
#include<ctype>
#include<algorithm>int main(void) {using namespace std;string input;bool isPal(string);string tmp = "";cout << "Enter a string(empty string to quit):";while (getline(cin,input) && input.size() > 0) {if (isPal(tmp))cout << "It's a palindrome." << endl;else {cout << "It isn't a palindrome" << endl;}cout << "Enter a string(empty string to quit):";}
}bool isPal(std::string s) {std::string r(s.rbegin(), s.rend());if (r == s)return true;elsereturn false;
}

第二题

要求:第一题拓展,加上输入字符串中有大小写、空格和标点符号的情况,程序需要将这些忽略掉

解答:

#include<iostream>
#include<string>
#include<ctype>
#include<algorithm>int main(void) {using namespace std;string input;bool isPal(string);string tmp = "";cout << "Enter a string(empty string to quit):";while (getline(cin,input) && input.size() > 0) {for (auto e : input) {if (isalpha(e))tmp.push_back(tolower(e));}if (isPal(tmp))cout << "It's a palindrome." << endl;else {cout << "It isn't a palindrome" << endl;}cout << "Enter a string(empty string to quit):";}
}bool isPal(std::string s) {std::string r(s.rbegin(), s.rend());if (r == s)return true;elsereturn false;
}

第三题

要求:从文件中读取单词,利用vector存储并输出到屏幕上,并打印个数

解答:

1.在.cpp文件目录下新建text文件“data.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

2.

#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<vector>int main() {using namespace std;ifstream fin("data.txt");string input;vector<string>v1;while (fin >> input) {v1.push_back(input);}copy(v1.begin(), v1.end(), ostream_iterator<string, char>(cout, " "));//打印单词cout << endl << "共计" << v1.size() << "个单词";fin.close();cout << endl;system("pause");return 0;
}

第四题

要求:编写一个具有老式风格的接口函数,原型如下

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

实参应是数组名和数组元素个数,该函数对数组进行排序,删除重复值,返回缩减后数组中的元素数目。用STL函数编写。

解答:

#include<iostream>
#include<list>
#include<iterator>int main() {using namespace std;int reduce(long[], int);long arr[] = { 1,4500,3120, 2791, 3200, 14, 560, 14, 3120, 3200, 3200, 3200 };//测试数组cout << "调用reduce前,数组元素依次如下" << endl;for (long e : arr) {cout << e << " ";}int count = sizeof(arr) / sizeof(long);cout << endl << "共有" << count << "个元素" << endl;count = reduce(arr, count);cout << "调用reduce后,数组元素依次如下" << endl;for (int i = 0; i < count; i++) {cout << arr[i] << " ";}cout << endl << "共有" << count << "个元素" << endl;cout << endl;system("pause");return 0;
}int reduce(long arr[], int n) {std::list<long> myList;std::copy(arr, arr + n, std::back_insert_iterator<std::list<long>>(myList));myList.sort();myList.unique();int i = 0;for (long e : myList) {arr[i++] = e;}return myList.size();
}

第五题

要求:与第四题相同,但要编写的是模板函数,并用long实例和string实例测试

解答:

#include<iostream>
#include<list>
#include<iterator>
#include<string>template<typename T>
void out(T arr[],int n);//因为long和string对象均可用cout打印,因此这里简化代码也用了模板template <typename T>
int reduce(T arr[], int n);using namespace std;int main() {long arr[] = { 1,4500,3120, 2791, 3200, 14, 560, 14, 3120, 3200, 3200, 3200 };//测试数组string arr2[] = { "haha", "heihei", "hehe", "haha", "haha", "heihei" };out(arr,sizeof(arr)/sizeof(long));out(arr2, sizeof(arr2) / sizeof(string));cout << endl;system("pause");return 0;
}template<typename T>
void out(T arr[],int n) {cout << "调用reduce前,数组元素依次如下" << endl;int count = n;for (int i = 0; i < count; i++) {cout << arr[i] << " ";}cout << endl << "共有" << count << "个元素" << endl;count = reduce(arr, count);cout << "调用reduce后,数组元素依次如下" << endl;for (int i = 0; i < count; i++) {cout << arr[i] << " ";}cout << endl << "共有" << count << "个元素" << endl;
}template <typename T>
int reduce(T arr[], int n) {std::list<T> myList;std::copy(arr, arr + n, std::back_insert_iterator<std::list<T>>(myList));myList.sort();myList.unique();int i = 0;for (T e : myList) {arr[i++] = e;}return myList.size();
}

第六题

要求:用STL模板类queue实现ATM模拟,允许用户输入三个数:队列的最大长度、程序模拟的持续时间(单位为小时)和平均每小时的客户数。程序使用循环,每次循环代表一分钟。在每分钟的循环中,程序将完成下面的工作:

  1. 判断是否来了新客户。如果来了,且此时队列未满,则将它添加到队列中,否则拒绝客户入队;
  2. 如果没有客户在进行交易,则选取队列的第一个客户。确定该客户的已等候时间,并将waitTime计数器设置为新客户所需的处理时间。
  3. 如果客户正在处理中, 则将waitTime计数器减1.
  4. 记录各种数据,如获得服务的客户数目、被拒绝的客户数目、排队等候的累积时间以及累积的队列长度等。

当模拟循环结束时, 程序将报告各种统计结果。

解答:

为了更多地利用STL,并完成一个稍完整的ATM小系统,这里把本题复杂化,写得比较多

//---ATM.h
#pragma once
#include<ctime>
#include<queue>
#include<vector>
using namespace std;//尽管这里其实没必要数据封装以及继承,但为了迎合OOP思想,还是写个类吧class ATM {
private:int maxLength;time_t startTime;double duration;int averageClientNum;queue<time_t> line;vector<time_t> comeTime;int currentLeftTime = 0;double totalWaitingTime = 0;int totalLineLength = 0;int currentClientNum = 0;int rejectClientNum = 0;void circle();void createComeTime();bool isCome();bool isFull();void enter();void reject();void deal();int getDealTime();time_t getWaitingTime(time_t before);int getCurrentClientNum();int getRejectClientNum();double getTotalWaitingTime();int getTotalLineLength();void over();public:ATM(int maxL = 3, double dur = 24, int aver = 40) :maxLength(maxL), duration(dur), averageClientNum(aver) {};void work();};
//--ATP.cpp
#include "ATM.h"
#include<iostream>
#include<ctime>
#include<queue>
#include<vector>
#include<Windows.h>using namespace std;#define MAXDEALTIME 5void ATM::over()
{cout << "------------------" << endl;cout << "当前统计结果如下" << endl;cout << "------------------" << endl;cout << "获得服务的客户数目:" << getCurrentClientNum() << endl;cout << "被拒绝的的客户数目:" << getRejectClientNum() << endl;cout << "排队等候的累积时间:" << getTotalWaitingTime() << endl;cout << "累积的队列长度:" << getTotalLineLength() << endl;
}void ATM::work()
{//这方便测试,假设一小时是一分钟;一分钟是一秒;startTime = time(0);double minutes = 60 * duration;createComeTime();cout << "ATM开始运行" << endl;while (static_cast<double>(time(0) - startTime) <= minutes) {Sleep(1000);circle();}cout << "时间到,ATM运行结束" << endl;
}void ATM::circle()
{cout << "---------------------------------------------------------------------" << endl;if (isCome()) {if (isFull()) {cout << "当前队列已满" << endl;reject();}else {enter();if (currentLeftTime == 0) {deal();currentLeftTime = getDealTime();}}}else {cout << "没有客户前来" << endl;}if (currentLeftTime > 0) {currentLeftTime--;cout << "当前客户交易剩余时间为" << currentLeftTime << endl;if(currentLeftTime == 0)cout << "当前客户交易结束" << endl;}over();cout << "本轮循环结束" << endl;cout << "---------------------------------------------------------------------" << endl;
}void ATM::createComeTime()
{srand(time(NULL));int totalClientNum = duration * averageClientNum;time_t cometime;for (int i = 0; i < totalClientNum; i++) {cometime = (rand() % static_cast<long>(60 * duration-1)) + startTime+1;comeTime.push_back(cometime);}sort(comeTime.begin(), comeTime.end());
}bool ATM::isCome()
{time_t currentTime = time(NULL);if (comeTime.size() > 0 && comeTime.front() <= currentTime)return true;return false;
}bool ATM::isFull()
{if (line.size() >= maxLength)return true;return false;
}void ATM::enter()
{line.push(comeTime.front());double waitingTime =static_cast<double>(getWaitingTime(comeTime.front()));totalWaitingTime += waitingTime;cout << "新客户已入队,他已等候时间为" << waitingTime << endl;totalLineLength++;}void ATM::reject()
{cout << "入队请求被拒" << endl;comeTime.erase(comeTime.begin());rejectClientNum++;
}void ATM::deal()
{totalWaitingTime += static_cast<double>(time(NULL) - line.front());line.pop();cout << "当前客户交易开始" << endl;comeTime.erase(comeTime.begin());currentClientNum++;
}int ATM::getDealTime()
{return rand() % MAXDEALTIME+1;
}time_t ATM::getWaitingTime(time_t before)
{return time(NULL) - before;
}int ATM::getCurrentClientNum()
{return currentClientNum;
}int ATM::getRejectClientNum()
{return rejectClientNum;
}double ATM::getTotalWaitingTime()
{return totalWaitingTime;
}int ATM::getTotalLineLength()
{return totalLineLength;
}
//--main.cpp
#include"ATM.h"int main(void) {using namespace std;int maxLength, averageClientNum;double duration;cout << "请输入队列最大长度:";cin >> maxLength;cout << "请输入程序模拟的持续时间(单位为小时):";cin >> duration;cout << "请输入平均每小时的客户数:";cin >> averageClientNum;ATM atm1(maxLength, duration, averageClientNum);atm1.work();cout << endl;system("pause");return 0;
}

第七题

使用了random_shuffle,用法陈旧因此弃掉

第八题

题目:

Mat和Pat希望邀请他们的朋友来参加派对。他们分别输入自己的朋友姓名列表,然后将两人的朋友姓名列表合并,得到不重复的被邀请者名单。

解答:

分析后可知,采用STLset容器极其相关算法最为简单,也就是求并集的过程,但注意set_union同copy一样,最后的一个参数要求输出迭代器且被输出容器容量足够,不能用C.begin(),因此采用insert_iterator构造输出迭代器

#include<iostream>
#include<iterator>
#include<set>
#include<vector>
#include<algorithm>
#include<string>int main(void) {using namespace std;void input(string, set<string>&);set<string>nameList1, nameList2, nameList3;input("Mat", nameList1);input("Pat", nameList2);set_union(nameList1.begin(), nameList1.end(), nameList2.begin(), nameList2.end(), insert_iterator<set<string>>(nameList3, nameList3.begin()));cout << "最终得出的邀请名单如下:" << endl;for (string e : nameList3) {cout << e << endl;}cout << endl;system("pause");return 0;
}void input(std::string name, std::set<std::string>& s) {std::cout << "请输入" << name << "的朋友名单(以空格分隔,回车结束):";std::string tmp;std::vector<std::string> v;while (std::cin >> tmp) {v.push_back(tmp);if (std::cin.get() == '\n')break;}std::copy(v.begin(), v.end(), std::insert_iterator<std::set<std::string>>(s,s.begin()));
}

第九题

要求:利用ctime中的clock()和STL完成下列目的

  1. 创建大型vector<int>对象vi0, 并使用rand()给它赋初值;
  2. 创建vector<int>对象vi和list<int>对象li, 它们的长度和初始值与vi0相同;
  3. 计算使用STL算法sort()对vi进行排序所需的时间,再计算使用list的方法sor()对li进行排序所需的时间。
  4. 将li重置为排序的vi0内容,并计算执行如下操作所需的时间:将li的内容复制到vi中,对vi进行排序,并将结果复制到li中。

解答:

#include<iostream>
#include<vector>
#include<algorithm>
#include<ctime>
#include<random>
#include<list>
#include<iterator>using namespace std;clock_t getTime(list<int>&li);
clock_t getTime(vector<int>&vi);
clock_t getTime(list<int>&li, vector<int>&vi);
void copy2(list<int>& li, vector<int>&vi);int main(void) {int getRandom(int e);vector<int>vi0(1000);vector<int>vi;list<int>li;random_device dev;uniform_int_distribution<int> dist(-100, 100);for (auto &e : vi0) {e = dist(dev);}copy(vi0.begin(), vi0.end(), insert_iterator<vector<int>>(vi, vi.begin()));copy(vi0.begin(), vi0.end(), insert_iterator<list<int>>(li, li.begin()));cout << "初始化完成" << endl;cout << "使用sort()对vi进行排序所需的时间为:" << getTime(vi) << endl;cout << "使用li.sort()对li进行排序所需的时间为:" << getTime(li) << endl;cout << "先将li拷贝到vi在对vi使用STL sort()排序后再拷贝会li所需的时间为:" << getTime(li,vi) << endl;cout << endl;system("pause");return 0;
}clock_t getTime(list<int>&li) {clock_t start = clock();li.sort();return clock() - start;
}clock_t getTime(vector<int>&vi) {clock_t start = clock();sort(vi.begin(),vi.end());return clock() - start;
}clock_t getTime(list<int>&li, vector<int>&vi){clock_t start = clock();copy2(li, vi);return clock() - start;
}void copy2(list<int> &li, vector<int> &vi) {vi.clear();for (int e : li) {vi.push_back(e);}sort(vi.begin(), vi.end());li.clear();for (int e : vi) {li.push_back(e);}
}

第十题

原题没意思,这里我加以改编题目拓展了一下。

要求:实现一个书单相关功能,使其能够实现如下功能(使用vector<shared_ptr<Review>>存储书籍信息)

  1. 按原始顺序显示
  2. 按字母表顺序显示
  3. 按评级升序显示
  4. 按评级降序显示
  5. 按价格升序显示
  6. 按价格降序显示
  7. 退出

假设书单内容为如下:

  1. Harry Potter and the Goblet of Fire    9     ¥68.5
  2. To Kill a Mockingbird      7     ¥78
  3. Pride and Prejudice        8     ¥70.50
  4. Fifty Shades of Grey     5  ¥71
  5. Great Expectations     7   ¥ 45

解答:

#include<iostream>
#include<vector>
#include<memory>
#include<string>
#include<algorithm>
#include<iterator>using namespace std;
typedef struct Review {string name;int rate;double price;
}Review;class BookList {
private:vector<shared_ptr<Review>> books;static bool cmpByAlpha(shared_ptr<Review> first, shared_ptr<Review> second);static bool cmpByRate(shared_ptr<Review> first, shared_ptr<Review> second);static bool cmpByPrice(shared_ptr<Review> first, shared_ptr<Review> second);void out(vector<shared_ptr<Review>> b = {});
public:BookList(vector<shared_ptr<Review>> &arr);void outByInit();void outByAlpha(bool sequence = true);void outByRate(bool sequence = true);void outByPrice(bool sequence = true);
};bool BookList::cmpByAlpha(shared_ptr<Review> first, shared_ptr<Review> second)
{if(first->name >= second->name)return false;return true;
}bool BookList::cmpByRate(shared_ptr<Review> first, shared_ptr<Review> second)
{if (first->rate >= second->rate)return false;elsereturn true;
}bool BookList::cmpByPrice(shared_ptr<Review> first, shared_ptr<Review> second)
{if (first->price >= second->price)return false;elsereturn true;
}void BookList::out(vector<shared_ptr<Review>> b)
{if (b.size() == 0)b = books;for (auto e : b) {cout << "-----------------------------" << endl;cout << "name: " << e->name << endl;cout << "rate: " << e->rate << endl;cout << "price: ¥" << e->price << endl;cout << "-----------------------------" << endl << endl;}
}BookList::BookList(vector<shared_ptr<Review>> &arr)
{for (auto e : arr) {books.push_back(e);}
}void BookList::outByInit()
{cout << "按原序输出如下" << endl;out();
}void BookList::outByAlpha(bool sequence)
{vector<shared_ptr<Review>> books2;copy(books.begin(), books.end(), insert_iterator<vector<shared_ptr<Review>>>(books2, books2.begin()));if (sequence) {cout << "按字母升序输出如下" << endl;sort(books2.begin(), books2.end(), BookList::cmpByAlpha);}else {cout << "按字母降序输出如下" << endl;sort(books2.rbegin(), books2.rend(), BookList::cmpByAlpha);}out(books2);
}void BookList::outByRate(bool sequence)
{vector<shared_ptr<Review>> books2;copy(books.begin(), books.end(), insert_iterator<vector<shared_ptr<Review>>>(books2, books2.begin()));if (sequence) {cout << "按评级升序输出如下" << endl;sort(books2.begin(), books2.end(), BookList::cmpByRate);}else {cout << "按评级降序输出如下" << endl;sort(books2.rbegin(), books2.rend(), BookList::cmpByRate);}out(books2);
}void BookList::outByPrice(bool sequence)
{vector<shared_ptr<Review>> books2;copy(books.begin(), books.end(), insert_iterator<vector<shared_ptr<Review>>>(books2, books2.begin()));if (sequence) {cout << "按价格升序输出如下" << endl;sort(books2.begin(), books2.end(), cmpByPrice);}else {cout << "按价格降序输出如下" << endl;sort(books2.rbegin(), books2.rend(), cmpByPrice);}out(books2);
}int main(void) {int showMenu();vector<shared_ptr<Review>> arr = { shared_ptr<Review>(new Review{"Harry Potter and the Goblet of Fire",9,68.5}),shared_ptr<Review>(new Review{"To Kill a Mockingbird", 7, 70.50}),shared_ptr<Review>(new Review{"Pride and Prejudice", 8, 70.50}),shared_ptr<Review>(new Review{" Fifty Shades of Grey", 5, 71.0}),shared_ptr<Review>(new Review{"Great Expectations", 7, 45.0}),};BookList list1(arr);int option;while ((option = showMenu()) != 0) {switch (option){default:continue; break;case 1:list1.outByInit(); break;case 2:list1.outByAlpha(); break;case 3:list1.outByAlpha(false); break;case 4:list1.outByRate(); break;case 5:list1.outByRate(false); break;case 6:list1.outByPrice(); break;case 7:list1.outByPrice(false); break;}system("pause");system("cls");}cout << endl;system("pause");return 0;
}int showMenu() {cout << "本程序是一个书单打印程序,请输入整数0-7选择打印方式" << endl;cout << "1.按原序打印;" << endl;cout << "2.按字母升序打印;" << endl;cout << "3.按字母降序打印;" << endl;cout << "4.按评级升序打印;" << endl;cout << "5.按评级降序打印;" << endl;cout << "6.按价格升序打印;" << endl;cout << "7.按价格降序打印;" << endl;cout << "0.退出;" << endl;int input;cin >> input;return input;
}

这里尤其注意一个点,自定义的谓词函数不能是稳定的,因为sort()非稳定算法。所以应是当">="时返回顺序错误(false),而写“>”会报错。

C++学习笔记——C++ Primer Plus中文第六版 第十六章STL编程练习解答相关推荐

  1. C Primer Plus (第六版) 第十四章_编程练习答案

    no1.c //重新编写复习题5,用月份名的拼写代替月份号(别忘了用strcmp()).在一个简单的程序中测试该函数 # include <stdio.h> # include <s ...

  2. C++ Primer Plus(第六版) 第4章 课后编程题

    1.输出下列的信息:名字包含多个字母:程序中将下调整成绩,向上调整一个字母 What is your first name? Betty Sue What is your last name? Yew ...

  3. c++primer plus第六版第十二章第一题

    //h文件 #pragma once class cow {char name[20];char*hobby;double weight; public:cow();cow(const char*m, ...

  4. 《C Primer Plus》第六版 第十二章第二题 编程练习

    好的,既然上次已经发了博客,那就不算萌新了....... 编译环境:VS 2017 (Community) 运行环境: Win 10 × 64 上题目: /* 12-2 ---在美国,通常以英里/加仑 ...

  5. Java基础学习——第十四章 网络编程

    Java基础学习--第十四章 网络编程 一.网络编程概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信 ...

  6. 《C++ Primer中文版(第五版)》 第九章 顺序容器

    <C++ Primer中文版(第五版)> 第九章 顺序容器 元素在顺序容器中的顺序与其加入容器时的位置相对应.关联容器中元素的位置由元素相关联的关键字值决定. 所有容器都共享公共的接口,不 ...

  7. C primer plus(第六版)第十一章源代码

    C primer plus(第六版)第十一章源代码 /* 11.1 */ #include<stdio.h> #define MSG "I am a symbolic strin ...

  8. Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)

    Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...

  9. <学习笔记>从零开始自学Python-之-web应用框架Django( 十)通用模板

    django相对于flask这种轻框架来说被称为全栈框架,因为它提供了相当多集成好的功能,比如前面讲了模板,其实Django提供了一些通用模板,它们可以让开发人员编写少量代码就能快速实现常见的数据视图 ...

  10. 【c++ primer】第五版第十四章习题答案

    第十四章 重载运算与类型转换 练习14.1 在什么情况下重载的运算符与内置运算符有所区别?在什么情况下重载的运算符又与内置运算符一样? 解: 不同点: 重载操作符不保证操作数的求值顺序,例如对& ...

最新文章

  1. C#格式化数值结果表(格式化字符串)
  2. 前端基本功—javascript 第三天
  3. a[0]和a 的区别?
  4. node.js编程错误记录集
  5. Web开发之三:前后端开发任务量分析与比较
  6. 【Java】java.util.Objects 工具类方法研究
  7. PHP函数func_get_args(),func_get_arg(),func_num_args()
  8. 16.深入分布式缓存:从原理到实践 --- 新的旅程
  9. php fpm过多,Linux下php-fpm进程过多导致内存耗尽问题解决
  10. JDK:native2ascii命令详解
  11. 时速云CEO:相对于IaaS和PaaS,未来CaaS将如何定位?
  12. 开源框架ZedGraph的使用
  13. python语言实现医院管理系统
  14. canvas画线变粗变模糊的解决办法
  15. 道阻且长 行者将至 ——新高考下的教学策略
  16. Gartner ABI报告技术解读:2021 BI 与数据分析魔力象限
  17. IOS开发使用@IBInspectable给控件添加额外属性
  18. 分享一些新员工培训的经验和想法
  19. lib和lib64的区别
  20. python输入直角三角形a、b、输出斜边c_编写Python程序,从键盘输入直角三角形两直角边a,b,求斜边c,并输出....

热门文章

  1. 在计算机控制交流电机过程中,交流电机的直流驱动方法、系统及利用该系统的同步电机与流程...
  2. Google Earth Engine(GEE)计算降水量偏差
  3. 为树莓派CM4 Raspberry Pi OS平台编译WiFi6(AX200和AX210)驱动
  4. CSS中行内元素与块级元素-FF浏览器dt中的h2,h3溢出
  5. 小米10s参数详细参数
  6. 第三周项目一---顺序表的基本运算
  7. 【学习总结Day22】
  8. 从DevOps到BizDevOps趋势篇:低代码正当其时
  9. plsql连接oracle模糊查询中文不成功
  10. 2020-04-06数据库具体操作