C++:【练习题】STL程序设计

习题1

1.1 题目:

某种聊天工具,每个好友的id都是唯一的,当用户接收到信息后,如果会话窗口之前没有与该好友的聊天信息,则在通信列表里,会将新接收的消息的好友id置顶,如果会话窗口中已有与该好友的聊天信息,则将该好友的id移动到通讯列表的顶端。请根据要求实现该功能。

输入:第一行为整数N,代表有N组测试数据,接下来的N组测试中,第一行为整数T,代表有T条通讯,第二行有T个整数,按时间先后顺序表示接收到讯息的好友id。

输出:按照通讯列表从上到下的顺序输出好友id,每个id以空格分隔。

样例输入:

3
5
1 2 3 4 5
6
1 2 3 3 2 1
7
1 5 2 2 1 7 1

样例输出:

5 4 3 2 1
1 2 3
1 7 2 5

1.2 解题思路:

  • 我们选用vector来作为存储结构。
  • 我们规定vector的末尾为最新数据。
  • 编写模板函数ChangeID,用于将数据类型id插入vector内。
  • 编写函数模板Display,用于将vector内的数据展示。
  • 编写主函数进行测试。

1.3 代码及注释:

#include<iostream>
#include<vector>
using namespace std;
// 我们规定vector的末尾为最新数据

// 编写函数模板ChangeID,用于将数据类型id插入vector内
template<typename T>
void ChangeID(vector<T>& vec, T id) {
	int size = vec.size();
	for (int i = 0; i < size; i++) {
		// 删除已存在的数据
		if (vec[i] == id) {
			vec.erase(vec.begin() + i);
			break;
		}
	}
	// 添加数据在最后面
	vec.push_back(id);
}

// 编写函数模板Display,用于将数据展示
template<typename T>
void Display(vector<T>& vec) {
	int size = vec.size();
	// 末尾为最新数据,故从后往前输出
	for (int i = size - 1; i >= 0; i--)
		cout << vec[i] << " ";
	cout << endl;
}

int main() {
	cout << "输入:" << endl;
	// 测试次数
	int test_times;
	cin >> test_times;
	vector<int>* int_vec = new vector<int>[test_times];
	// 输入每次测试的数据
	for (int i = 0; i < test_times; i++) {

		int length;
		cin >> length;
		for (int j = 0; j < length; j++) {
			int id;
			cin >> id;
			ChangeID(int_vec[i], id);
		}
	}
	cout << endl << "输出:" << endl;
	// 展示每次测试的结果
	for (int i = 0; i < test_times; i++) {
		Display(int_vec[i]);
	}
	return EXIT_SUCCESS;
}

1.4 程序运行结果分析:

输入:
3
5
1 2 3 4 5
6
1 2 3 3 2 1
7
1 5 2 2 1 7 1

输出:
5 4 3 2 1
1 2 3
1 7 2 5

D:\Private\Files\C++\高级语言程序设计2-2\第九章作业\Project1\Debug\Project1.exe (进程 12040)已退出,代码为 0。
按任意键关闭此窗口. . .

验证可得程序执行正确。

习题2

2.1 题目:

在一项比赛中,有五位参赛选手分别是A、B、C、D、E,设计一个Player类,数据成员包括选手的姓名和分数。选手的分数按照如下方式产生:10名裁判对每位选手打分,去掉一个最高分,再去掉一个最低分,剩余的分数取平均值。最后按照分数从高到低的顺序输出选手的姓名和得分信息。
提示和要求:用STL完成本题目,用vector容器存放每位选手的信息,每位选手的分数可放入双端队列中,用sort()排序后去掉两端,再求平均值,用sort()对vector排序(需用到自定义排序规则,网上自行搜索)

2.2 解题思路:

  • 构建Player类,创建成员变量score和name 。
  • 编写Player类的成员函数,用于设置和获取score和name。
  • 利用vector容器存储五个Player对象。
  • 利用deque的特点对10个分数进行存储。
  • 利用sort函数对deque进行排序。
  • 去除最高分和最低分后会Player对象属性进行设置。
  • 编写SortPlayer函数自定义比较方式。
  • 利用sort函数对vector进行自定义排序。
  • 编写Display函数输出vector内所有的Player对象的名字和成绩,由高到低。
  • 主函数内自定义数据进行检测。

2.3 代码及注释:

#include<iostream>
#include<deque>
#include<vector>
#include <algorithm>
#include<iomanip>

using namespace std;

// 构造Player类
class Player {
public:
	Player() {}
	// 设置分数
	void SetScore(double s) { score = s; }
	// 设置名字
	void SetName(char* n) {
		char* p = new char[strlen(n) + 1];
		name = p;
		strcpy_s(name, strlen(n) + 1, n);
	}
	// 获取分数
	double GetScore() { return score; }
	// 获取名字
	char* GetName() { return name; }
private:
	// 最终得分
	double score;
	// 名字
	char* name;
};

// 创建比较函数
bool SortPlayer(Player& a, Player& b) {
	return a.GetScore() > b.GetScore();
}

// 创建展示函数
void Display(vector<Player>& vec) {
	cout << endl << "  *** Final Result *** " << endl;
	int size = vec.size();
	cout.setf(ios::left);
	for (int i = 0; i < size; i++)
		cout << "Name: " << setw(10) << vec[i].GetName() << "Score: " << vec[i].GetScore() << endl;
}

int main() {
	vector<Player> players;
	for (int i = 0; i < 5; i++) {
		Player player;
		char name[20];
		cin >> name;
		// 设置姓名
		player.SetName(name);
		// 利用双端队列保存10个数据
		deque<double> scores;
		for (int j = 0; j < 10; j++) {
			double s;
			cin >> s;
			scores.push_back(s);
		}
		// 进行排序
		sort(scores.begin(), scores.end());
		// 去除最高分和最低分
		scores.pop_back();
		scores.pop_front();
		double total_score = 0;
		// 求总分
		for (auto iter = scores.begin(); iter != scores.end(); iter++) 
			total_score += *iter;
		// 设置分数
		player.SetScore(total_score / 8);
		players.push_back(player);
	}
	// 对vector进行排序,自定义规则SortPlayer函数
	sort(players.begin(), players.end(), SortPlayer);
	// 展示最后结果
	Display(players);
    return EXIT_SUCCESS;
}

2.4 程序运行结果分析:

我们自定义输入数据:

Jack 8.3 9.9 9.7 8.8 8.9 9.9 9.1 8.9 9.0 8.5
Mike 9.9 7.3 7.2 7.4 7.5 7.1 7.3 7.4 7.2 6.3
Rose 5.5 3.6 5.4 8.5 5.2 5.6 5.0 5.6 5.0 5.9
Nick 9.8 7.9 8.2 8.2 8.1 7.1 8.2 8.1 8.1 8.0
Michael 3.0 2.9 3.0 2.9 3.0 2.6 5.4 3.0 2.8 2.1

进行检测,结果如下:

Jack 8.3 9.9 9.7 8.8 8.9 9.9 9.1 8.9 9.0 8.5
Mike 9.9 7.3 7.2 7.4 7.5 7.1 7.3 7.4 7.2 6.3
Rose 5.5 3.6 5.4 8.5 5.2 5.6 5.0 5.6 5.0 5.9
Nick 9.8 7.9 8.2 8.2 8.1 7.1 8.2 8.1 8.1 8.0
Michael 3.0 2.9 3.0 2.9 3.0 2.6 5.4 3.0 2.8 2.1

  *** Final Result ***
Name: Jack      Score: 9.1
Name: Nick      Score: 8.1
Name: Mike      Score: 7.3
Name: Rose      Score: 5.4
Name: Michael   Score: 2.9

D:\Private\Files\C++\高级语言程序设计2-2\第九章作业\Project2\Debug\Project2.exe (进程 20860)已退出,代码为 0。
按任意键关闭此窗口. . .

因此,程序执行正确。

习题3

3.1 题目:

有两组数据分别是{10,15,2,8,22,11}、{1,5,10,22,4,8,33,6},将这两组数据分别存储在list容器中,并将两个链表合并,合并之后删除重复元素,对链表中的值从小到大排序。

3.2 解题思路:

  • 用list容器存储两组数据。
  • 用list容器的splice函数进行合并list。
  • 用list容器的sort函数进行排序。
  • 用list容器的unique函数进行去除临近的重复元素。
  • 在主函数内实现并输出。

3.3 代码及注释:

#include<iostream>
#include<list>

using namespace std;

int main() {
	int a[6] = { 10,15,2,8,22,11 };
	int b[8] = { 1,5,10,22,4,8,33,6 };
	list<int> a_list(a, a + 6);
	list<int> b_list(b, b + 8);
	list<int>::iterator iter;
	// 输出第一个链表
	cout << "第一个list:";
	for (iter = a_list.begin(); iter != a_list.end(); iter++)
		cout << *iter << " ";
	// 输出第二个链表
	cout << endl << "第二个list:";
	for (iter = b_list.begin(); iter != b_list.end(); iter++)
		cout << *iter << " ";
	// 输出合并的链表
	cout << endl << "合并之后的list:";
	a_list.splice(a_list.end(), b_list);
	for (iter = a_list.begin(); iter != a_list.end(); iter++)
		cout << *iter << " ";
	// 删除重复数据后从小到大排序
	cout << endl << "删除重复元素后小到大排序的list:";
	a_list.sort();
	a_list.unique();
	for (iter = a_list.begin(); iter != a_list.end(); iter++)
		cout << *iter << " ";
	cout << endl;

	return EXIT_SUCCESS;
}

3.4 程序运行结果分析:

结果如下:

第一个list:10 15 2 8 22 11
第二个list:1 5 10 22 4 8 33 6
合并之后的list:10 15 2 8 22 11 1 5 10 22 4 8 33 6
删除重复元素后小到大排序的list:1 2 4 5 6 8 10 11 15 22 33

D:\Private\Files\C++\高级语言程序设计2-2\第九章作业\Project3\Debug\Project3.exe (进程 18864)已退出,代码为 0。
按任意键关闭此窗口. . .

验证三组测试实验表明,程序执行正确。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值