基础c++学习 day01

容器

  • vector:当你需要一个可以动态改变大小的数组,并且主要进行尾部插入和删除操作时,使用vector是最好的选择。vector提供了随机访问,所以如果你需要经常访问元素,vector也是一个好选择。

  • set:当你需要一个集合来存储唯一元素,并且需要快速检查一个元素是否在集合中时,使用set是最好的选择。set内部通常实现为红黑树,插入,删除和查找时间复杂度都是O(log n)。

  • map:当你需要基于键值对存储和检索数据时,使用map是最好的选择。map提供了O(log n)的搜索,删除和插入操作。

以下是vector,set和map这三种容器的增删查改方式的对比:

操作vectorsetmap
插入push_back(value)insert(value)insert({key, value}) 或 map[key] = value
删除erase(iterator) 或 pop_back()erase(iterator) 或 erase(value)erase(key) 或 erase(iterator)
查找std::find(vec.begin(), vec.end(), value)set.find(value)map.find(key)
修改vec[index] = new_value不支持直接修改,需要删除后重新插入map[key] = new_value

注意,vector的查找操作是线性的,而set和map的查找操作是对数的。此外,set不支持直接修改元素,因为它是一个有序容器,直接修改元素可能会破坏其内部的排序。

练习1:

//1. vector练习:创建一个vector,
//添加10个随机生成的整数。
//删除所有偶数元素,并打印剩余的元素。
// *****
srand(time(0)); // 使用当前时间作为随机数生成器的种子
vector<int> vec;
for (int i = 0; i < 10; i++)
{
	int random_number = std::rand() % 100 + 1; // 生成1-100的随机数
	vec.push_back(random_number);
}
vec.erase(remove_if(vec.begin(), vec.end(), [](int i) {return i % 2 == 0; }), vec.end());
/*for (auto it = vec.begin(); it != vec.end(); ++it) //遍历的时候不能删除
{
	if (*it%2==0) {
		vec.erase(it);
	}
}*/
cout << "删除后" << endl;
for (int i = 0; i < vec.size(); i++)
{
	cout << vec[i] << endl;
}

注意第一个练习中的vector在遍历的时候不能进行添加和删除元素,因为一旦进行这个操作那他最后的迭代器就会失效,应该采用上述方式进行删除操作。
PS.两个重要函数详细解析:

  1. std::remove_if(vec.begin(), vec.end(), [](int i){return i%2 == 0;}):这是C++的std::remove_if函数,它接受三个参数:一个范围的开始和结束迭代器,以及一个谓词函数。这个函数会遍历指定的范围,并将所有满足谓词函数的元素移动到范围的末尾。在这个例子中,谓词函数是一个lambda函数,它接受一个整数i,并检查i是否是偶数。因此,std::remove_if函数会将vec中的所有偶数元素移动到vec的末尾。

  2. vec.erase(…, vec.end()):这是C++的std::vector::erase函数,它接受一个范围的开始和结束迭代器,并删除这个范围内的所有元素。在这个例子中,开始迭代器是std::remove_if函数的返回值,它指向vec中第一个偶数元素。结束迭代器是vec.end(),它指向vec的末尾。因此,vec.erase函数会删除vec中的所有偶数元素。

练习2:

// *****
//2.set练习:创建一个set,
//然后添加10个随机生成的整数。
// 然后,检查数字5是否在set中,
// 如果在,删除它,如果不在,添加它。
// 最后,打印set的所有元素。
set<int> se;
for (int i = 0; i < 10; i++)
{
	int random_number = std::rand() % 100 + 1;
	se.insert(random_number);// 插入值到se
}

if (se.find(5) != se.end()) { //find返回迭代器,要判断是否到末尾
	se.erase(5);
}
else
{
	se.insert(5);
}
cout << "set 删除后" << endl;
for (auto i = se.begin(); i != se.end(); i++)
{
	cout << *i << endl;
}

注意find并非返回bool值而是返回一个迭代器

练习3:

 // 创建一个map
map<string, int> myMap;

// 添加5个元素,键是随机生成的字符串,值是随机生成的整数
// 这里为了简化,我们使用固定的字符串和整数
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
myMap["four"] = 4;
myMap["five"] = 5;

// 查找键为"test"的元素
auto it = myMap.find("test");

// 如果找到,打印它的值
if (it != myMap.end()) {
	std::cout << "找到了键为\"test\"的元素,其值为:" << it->second << std::endl;
}
// 如果没有找到,插入一个新元素,键为"test",值为0
else {
	myMap["test"] = 0;
	std::cout << "没有找到键为\"test\"的元素,已插入新元素,其值为0" << std::endl;
}

// 打印map的所有元素
for (const auto &pair : myMap) {
	std::cout << "键:" << pair.first << ",值:" << pair.second << std::endl;
}

此处有个细节就是Pair这里加上一个引用,是为了节省内存,同时一般情况下可以通过引用修改源数据,但此处不需要那样做,于是加了const,但是有个问题就是如果不加也无法修改,因为map的键是个敞亮不能被修改,所以不要通过这个去修改

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值