通过这一周的学习,我对STL有了一些了解,下面我想从以下三个方面对本周学习获得的知识点进行分析与总结。
1、deque
对deque的分析,首先从一个打分案例开始:
一共有十位选手、五名评委,五名评委分别对十位选手进行打分,去掉一个最高分,去掉一个最低分,剩下三位评委的平均分即为该选手的最终得分,最后对十名选手按成绩由高到低进行排名。
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <string>
#include <time.h>
#include <stdlib.h>
using namespace std;
//首先定义一个选手类
class Player{
public:
Player(){}
Player(string name,int score):Name(name),Score(score){}
public:
string Name;
int Score;
};
//创建十位选手
void Ten_Player(vector<Player>& v)
{
string nameming = "ABCDEFGHIJ";
for (int i=0;i<10;i++)
{
Player x;
x.Name = "选手";
x.Name += nameming[i];
x.Score = 0;
v.push_back(x);
}
}
void PrintScore(int val)
{
cout << val << " ";
}
//利用随机数评委打分
void Set_Score(vector<Player>& v)
{
srand(time(NULL));
for (vector<Player>::iterator it = v.begin(); it != v.end();it ++)
{
//当前学生进行打分
deque<int> dScore;
for (int i = 0; i < 10;i++){
int score = rand() % 41 + 60;
cout << score << " ";
dScore.push_back(score);
}
cout << endl;
//对分数排序
sort(dScore.begin(),dScore.end());
//去除最高分 去除最低分
dScore.pop_front();
dScore.pop_back();
//求平均分
int totalScore = 0;
for (deque<int>::iterator d=dScore.begin(); d!=dScore.end(); d++)
{
totalScore += (*d);
}
int avScore = totalScore / dScore.size();
//保存分数
(*it).Score = avScore;
}
}
//排序
bool mycompare(Player& p1,Player& p2)
{
return p1.Score > p2.Score;
}
//根据选手分数排名 sort默认从小到大 希望从大到小
void Print_Rank(vector<Player>& v)
{
//进行比较排序
sort(v.begin(), v.end(), mycompare);
//输出
for (vector<Player>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "姓名:" << (*it).Name << "得分:" << (*it).Score << endl;
}
}
//主函数
int main(void)
{
vector<Player> vPlist;
Ten_Player(vPlist);
Set_Score(vPlist);
Print_Rank(vPlist);
return 0;
}
分析:
上述代码首先定义了一个类,在类中包括了选手的数据成员,通过随机数的方式代替评委的打分,将产生的分数存放到deque所声明的动态数组当中,对分数进行比较,利用deque的特点将最高分以及最低分删除,求出平均分后对平均分进行比较,最后输出排名。
总结:
在一周的学习中,我了解到对此类问题(比赛打分、公司员工统计、通讯录的增删等),运用deque可以更方便地在数组头部尾部以及中间插入元素,也可以获取或删除数组内元素,同时对数组的长度有一个动态的分配。若只是使用目前在程序设计课上所学的一维数组,无法操作数组内部元素。但通过阅读资料得知,deque的随机访问效率不如vector高,若要追求提高效率,vector使用较广。
2、优先队列——priority_queue
利用优先队列——priority_queue,首先我想到的是近期核酸检测排队系统,与queue先进先出的的特点,可以更方便的统计核酸检测人数,管理待测人员排队顺序,减少人流拥挤。若待测人员有急事,级数越大,则可优先检测。
#include<iostream>
#include<queue>
#include<ctime>
#include <cstdlib>
using namespace std;
int main(){
srand(time(NULL));
priority_queue<int> dl; //声明一个优先队列
for(int i = 0; i < 10; ++i){
int num = rand()%100;
dl.push(num); //随机数字进队列
cout << "待测人员在此队伍的号码:" << num <<endl;
}
while(!dl.empty()){
cout << dl.top() << " "; //输出队头元素
dl.pop();//测完之后之后出队
}
return 0;
}
分析:
对上述代码的加以改进,我认为,若定义一个类,类中包含两个数据成员,一个为人员紧急情况分为着急(1)与不着急(2),在此之下再对人员利用queue进行排序,会使队伍更有条理。与priority_queue所显示的效果相似。
总结:
优先队列在现实生活中应用广泛,像就医、银行业务办理、收银台等问题,均可用优先队列解决。但在这一方面,优先队列与类、数组等结合应用我不太熟练,每写一行代码都需要思考许久,还需要加以练习。
3、set / multiset 与 map / multimap
对set和multiset与map和multimap的掌握程度不如以上两个高,目前只学习了set和multiset与map和multimap的联系、区别,在实际问题中的应用还没有完全掌握,需要进一步学习。
对其可应用场景的猜测:
查找重复值,信息核对类问题:猜测原因——multiset可以允许元素重复,而set不允许元素重复;map不允许两个元素有相同的键值,而multimap可以。
大数据分析个人爱好类问题:猜测原因——multiset类型是一类集合,其特点是集合元素无序且可重复,若对一类事物访问量增多,则可认为是集合中一个元素的重复次数增多,即可得出此用户的兴趣爱好。
学生学号、员工工位类问题:猜测原因——map中的集合,元素是成对存在的,且map不允许两个元素有相同的键值,恰如学生姓名及其学号,每个学号对应了一个学生的姓名,学号不能重复,但是姓名可能会重复,员工工位问题亦是如此。
共同好友、相同之处类问题:猜测原因——set特点是集合元素无序且不可重复,利用set对列表好友(集合)进行分析查找,若有相同元素,则为共同好友。
以上是对第三周学习的总结,第四周会继续学习STL,并了解其它新知识。