【C++第三阶段】deque容器&评委打分案例

发布于:2024-04-11 ⋅ 阅读:(140) ⋅ 点赞:(0)

以下内容仅为当前认识,可能有不足之处,欢迎讨论!



deque容器

双端数组,可以对头端插入删除操作。

如下图所示。

image-20240409203254136

头部有插入删除操作,尾部亦然。有自己迭代器。有获取头部数据和尾部数据方法。

deque与vector区别

  • vector对于头部插入删除效率低,数据量越大,效率越低。
  • deque相对而言,头部插入删除速度比vector快。因为它有自己的中控器,连续存放一部分,再连续存放一部分。
  • vector访问元素速度会比deque快,这和两者内部实现有关。

deque容器和vector容器构造方式几乎一致,灵活使用即可。

需要说明一点,如果想要在打印容器时不对其修改,可以在入参&创建迭代器时,加上const关键字,使得引用&迭代器是静态的。

代码示例:

void print(const deque<int> &deq){
	for(deque<int>::const_iterator it = deq.begin() ; it!= deq.end();it++){
        cout<<*it<<",";
    }	
    cout<<endl;
    cout<<"==========="<<endl;
}

构造函数

以及几种构造函数:

deque<T> deqT;默认构造形式

deque(beg,end);构造函数将迭代器beg-end区间的元素拷贝给本身

deque(n,elem);构造函数将n个elem拷贝给本身

deque(const deque &deq);默认拷贝构造函数

代码示例:

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}

void test0409a() {
	deque<int> deq;
	for (int i = 0; i < 3; i++) {
		deq.push_front(i);
		deq.push_back(i * i + i);
	}
	print(deq);
	
	deque<int> deqv2(deq.begin(), deq.end());
	print(deqv2);

	deque<int> deqv3(3, 5);
	print(deqv3);

	deque<int> deqv4(deqv2);
	print(deqv4);
}

运行结果:

image-20240409211302523

赋值操作

三种方式

deque& operator=(const deque &deq);直接另一个容器等于,相当于重载等号操作符

assign(beg,end);将迭代器中的区间拷贝给本身。

assign(n,elem);将n个elem拷贝赋值给本身。

代码示例:

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}
void test0409b() {
	deque<int> deq;
	for (int i = 2; i < 9; i += 2) {
		deq.push_front( i * i - 2*i);
	}
	deque<int> deqv2 = deq;
	print(deqv2);

	deque<int> deqv3(deqv2.begin(), deqv2.end());
	print(deqv3);

	deque<int> deqv4(3, 5);
	print(deqv4);
	
}

运行结果:

image-20240409212540527

大小操作

有四种,列表格查看。

目的 函数
判断容器是否为空 deque.empty();
容器内元素个数 deque.size();
重新赋个数,如果超出,则截断,如果没超出,则默认值填充。 deque.resize(num);
重新赋个数,如果超出,则截断,如果每超出,则elem值填充。 deque.resize(num , elem);

代码示例

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}

void test0409c() {
	deque<int> deq;
	for (int i = 1; i < 5; i++) {
		deq.push_front(i * i + i * 2 - 5);
	}
	print(deq);
	cout << "容器个数是否为空?1为true,0为false" << deq.empty()<<" . " << endl;
	cout << "容器内元素个数:" << deq.size() << " . " << endl;
	deq.resize(4);
	print(deq);
	deq.resize(5, 2);
	print(deq);
}

运行结果:

image-20240409213336460

插入删除

插入操作:

目的 函数
在容器尾部添加一个数据 push_back(elem);
在容器头部插入一个数据 push_front(elem);
删除容器最后一个数据 pop_back();
删除容器第一个数据 pop_front();

指定位置插入:

目的 函数
在pos位置插入一个elem元素的拷贝,返回新数据的位置 insert(pos,elem);
在pos位置插入n个elem数据,无返回值 insert(pos,n,elem);
在pos位置插入[beg,end]区间的数据,无返回值 insert(pos,beg,end);

删除操作:

目的 函数
清空容器中所有数据 clear();
删除[beg,end]区间的数据,返回下一个数据的位置 erase(beg,end);
删除pos位置的数据,返回下一个数据的位置 erase(pos);

示例代码:

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}
void test0410a() {
	deque<int> deq;
	for (int i = 0; i < 3; i++) {
		//头部插入3个数据1,2,3
		deq.push_front(i);
	}
	for (int i = 8; i < 11; i++) {
		//尾部添加8,9,10
		deq.push_back(i);
	}
	//打印当前deque容器。
	print(deq);

	//删除容器最后一个数据
	deq.pop_back();
	cout << "删除最后一个数据后的容器为" << endl;
	print(deq);

	//删除容器第一个数据
	deq.pop_front();
	cout << "删除第一个数据的容器为:" << endl;
	print(deq);

	//在第1个位置插入一个数据elem
	//这里的位置是迭代器。
	deq.insert(deq.begin(), 2);
	cout << "在头部插入一个2后,容器为" << endl;
	print(deq);

	deq.insert(deq.end(),2, 100);
	cout << "在尾部插入2个100后,容器为" << endl;
	print(deq);

	deq.insert(deq.begin(), --deq.end(), deq.end());
	cout << "在头部插入当前数据的最后一个元素" << endl;
	print(deq);

	deq.erase(deq.begin(), ++deq.begin());
	cout << "删除第一个元素后,容器为" << endl;
	print(deq);

	deq.erase(deq.begin());
	cout << "删除最后一个元素,容器为" << endl;
	print(deq);

	deq.clear();
	cout << "当前容器是否为空?1为空,0为否" << endl;
	cout << deq.empty() << endl;


}

运行结果:

image-20240410204139416

erase不能直接删除最后一个元素,询问GPT结果:

因为end()指向的是下一个元素。

您的代码尝试使用deq.erase(deq.end());来删除deque的最后一个元素,但这会导致未定义行为并可能引发运行时错误。原因是deq.end()返回的迭代器指向容器末尾元素之后的位置,而不是最后一个元素本身。这意味着您试图从一个非法位置删除元素,因为.end()返回的迭代器并不指向有效的容器元素。

正确的做法是使用deq.erase(deq.end() - 1);来删除最后一个元素。不过,对于std::deque来说,这个表达式也是错误的,因为std::deque不支持随机访问迭代器的减法操作。对于std::deque,正确删除最后一个元素的方法是使用deq.pop_back();,这是专门用来移除容器尾部元素的成员函数。

数据存取

对deque的数据进行存取。这里的索引是索引,不是序号。

目的 函数
返回索引idx所指的数据 at(int index);
返回索引index所指的数据 operator[];
返回容器中第一个数据元素 front();
返回容器中最后一个数据元素 back();

代码示例:

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}
void test0410b() {
	deque<int> deq;
	for (int i = 0; i < 5; i++) {
		deq.push_back(i*i - 2 );
	}
	print(deq);

	cout << "第3个数据是:" << deq.at(2) << "." << endl;
	cout << "第4个数据是:" << deq[3] << endl;

	cout << "第一个数据是:" << deq.front() << "." << endl;
	cout << "最后一个数据是:" << deq.back() << "." << endl;
}

运行结果:

image-20240410205709698

排序

系统自带的算法,排序。要包含algorithm头文件。

示例代码:

void print(const deque<int>& deq) {
	for (deque<int>::const_iterator deq_it = deq.begin(); deq_it != deq.end(); deq_it++) {
		cout << *deq_it << " , ";
	}
	cout << endl;
	cout << "=======" << endl;
}
void test0410c() {
	deque<int> deq;
	for (int i = -3; i < 4; i++) {
		deq.push_back(i*i+2*i-3);
	}
	print(deq);
	sort(deq.begin(), deq.end());
	cout << "排序后" << endl;
	print(deq);
}

运行结果:

image-20240410210236989

对于支持随机访问的迭代器的容器,可以利用sort算法直接对其排序。

评委评分

案例描述

5名选手,10个评委分别对一名选手打分,去除最高分,去除最低分,获取平均分。

示例代码:

class Member {
	public:
		Member() {

		}
		Member(string name, int number) {
			this->member_name = name;
			this->set_score_number(number);
		}
	public:
		vector<int> score;
		int final_score;
		string member_name;

	private:
		int score_number ;
	public:
		void set_score_number(int number) {
			this->score_number = number;
		}
		int get_score_number() {
			return this->score_number;
		}
		int get_final_score() {
			
			for (int i = 0; i < score_number; i++) {
				final_score += score[i];
			}
			if (score_number == 2) {
				final_score = final_score / 2;
			}
			else if(score_number == 1) {
				return final_score;
			}
			else {

				score.pop_back();
				score.erase(score.begin());
				return final_score/score_number;
			}
			this->final_score = final_score;
			return final_score;
		}
};

void test0410d() {
	int eval_number;
	cout << "请输入评委人数:";
	bool eval_bool = true;
	while (eval_bool) {
		cin >> eval_number;
		if (eval_bool >= 0) {
			eval_bool = false;
		}
		else {
			cout << "请输入评委人数(>=0):";
		}
	}
	cout << endl;
	int single_number;
	cout << "请输入参赛人员人数:";
	bool single_bool = true;
	while (single_bool) {
		cin >> single_number;
		if (single_number >= 0) {
			single_bool = false;
		}
		else {
			cout << "请输入参赛人员人数(>=0):";
		}
	}
	cout << endl;
	vector<Member> vec_Members;
	for (int i = 0; i < single_number; i++) {
		cout << "请输入参赛人员姓名:";
		string temp_name;
		cin >> temp_name;
		Member temp(temp_name, eval_number);
		vec_Members.push_back(temp);
		//vec_Members[i].member_name = temp_name;
		//vec_Members[i].set_score_number(eval_number);
		//cout << endl;
	}
	cout << endl;
	vector<int> member_scores;
	for (vector<Member>::iterator mem = vec_Members.begin(); mem != vec_Members.end(); mem++)
	{
		cout << "当前参赛人员为:" << (*mem).member_name << "."<<endl;
		for (int i = 0; i < eval_number; i++) {
			int temp_score;
			cout << "请输入第" << i + 1 << "个评委的打分:";
			cin >> temp_score;
			(*mem).score.push_back(temp_score);
		}
		(*mem).final_score = (*mem).get_final_score();
		
		//cout << "当前参赛人员" << (*mem).member_name << "得分为:" << (*mem).final_score << endl;
		member_scores.push_back((*mem).final_score);
		cout << endl;
	}
	
	cout << endl;
	for (int i = 0; i < member_scores.size();i++) {
		cout << "当前选手" << vec_Members[i].member_name << "得分为\t" << member_scores[i] << "." << endl;
	}

	sort(member_scores.begin(),member_scores.end());
	float max_score = member_scores[member_scores.size()-1];

	cout << endl;
	cout << "比赛最高分为:" << max_score << endl;
	cout << endl;

	for (int i = 0; i < single_number; i++) {
		//cout << vec_Members[i].member_name << "得分为:" << vec_Members[i].final_score << "."<<endl;
		if (vec_Members[i].final_score == max_score) {
			cout<<"得分最高的选手为:"<<vec_Members[i].member_name<<"."<<endl;
		}
	}
}

运行截图:

image-20240410221645647


以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!

学吧,学无止境,太深了


网站公告

今日签到

点亮在社区的每一天
去签到