C++ stl初步(三)set,map 完结篇
函数:insert(x)erase(x) find(x)查找元素lower_bound(x) upper_bound(x)map使用红黑树(red_black tree),数据结构来实现,具有较快的插入,删除,查找操作的时间复杂度o(logN)map是一种关联容器,用于存储一组键值对(key-value pairs),其中每个键(key)都是唯一(不相同)的。set中的元素是唯一的,即不允许重复的
1,set
set是一种容器,用于存储一种唯一的元素,并按照一定的排序规则进行排序。set中的元素是按照升序排序的
默认情况下,它使用元素比较符(<)进行排序(升序)
结构:template<class Key(元素类型),class Compare=less<Key>(比较函数类型,默认为less),
class Allocator=allocator<Key>(用于分配内存的分配器类型,默认为allocator)>
class set;
set的内部实现了红黑树(一种自平衡的二叉搜索树)来存储元素,并保持元素的有序性
这使得在set中插入,删除和查找元素的时间复杂度都是对数时间,即o(logN)
set中的元素是唯一的,即不允许重复的元素在,当插入一个重复元素时,set会自动忽略该元素
函数:insert(x) erase(x) find(x)查找元素 lower_bound(x) upper_bound(x)
/*与upper_bound的对比
lower_bound(key):返回第一个大于等于key的元素。
upper_bound(key):返回第一个大于key的元素。
例如,对于set s = {1, 3, 5}:
s.lower_bound(3) 返回指向3的迭代器。
s.upper_bound(3) 返回指向5的迭代器。*/
equal_range(不常用) 以上均为o(logN)
size() empty()这两个为o(1) clear() o(N)
begin() end() rbegin()返回指向集合末尾位置的逆向迭代器
rend() 返回指向起始位置的逆向迭代器 以上均为o(1) swap(不常用)
修改set比较方法的常见手段:
1,原本是升序排列,加入greater后变成了降序
int main()
{
set<int, greater<int>>myset;
myset.insert(25);
myset.insert(17);
myset.insert(39);
myset.insert(62);
for (const auto& i : myset)
{
cout << i << " ";
}
cout << endl;
return 0;
}
2,
struct Mycompare//仿函数
{
bool operator()(const int& a, const int& b)
{
//自定义比较逻辑
return a > b;//改为降序
}
};
int main()
{
set<int, Mycompare>myset;
//............
return 0;
}
////////multiset多重集合
multiset是一种容器,与set类似,存储一种元素并进行排序存储
但是他不同于set,可以存储重复元素,结构我就不写了,懒得写
其函数和set一样,不写了
注意:在erase(x)中,例如{x,x,x,y,z}使用该函数会把所有x删除掉
正确方法:使用st.erase(st.find(x))
//////////////unordered_set无序集合
用于存储一组唯一的元素,没有特定的顺序。该容器使用哈希表来实现元素的存储和访问,因此
删除,插入,查找,都是o(1),但最坏o(n),不稳定
函数: insert erase find size count():返回元素在集合中出现的次数
代码示例:
1,set
int main()
{
set<int>myset;
//插入元素
myset.insert(5);
myset.insert(2);
myset.insert(8);
myset.insert(2);//重复元素
//遍历集合
cout << "set elements: ";
for (const auto& i : myset)
{
cout << i << " ";
}
cout << endl;//2 5 8
//查找元素
int sv = 5;
auto it = myset.find(sv);
if (it != myset.end())
{
cout << sv << "finded" << endl;
}
else
{
cout << sv << "can not find" << endl;
}
//移除元素
int rv = 2;
myset.erase(rv);
//再次遍历集合
cout << "set elements: ";
for (const auto& i : myset)
{
cout << i << " ";
}
cout << endl;//5 8
//清空集合
myset.clear();
//检查集合是否为空
if (myset.empty())
{
cout << "empty";
}
else
{
cout << "not empty";
}
return 0;
}
2,multiset
int main()
{
multiset<int>mymset;
//插入元素
mymset.insert(5);
mymset.insert(2);
mymset.insert(8);
mymset.insert(2);//重复元素
//遍历集合
cout << "set elements: ";
for (const auto& i : mymset)
{
cout << i << " ";
}
cout << endl;//2 2 5 8
//查找元素
int sv = 5;
auto range = mymset.equal_range(sv);
if (range.first != range.second)
{
cout << sv << "finded" << endl;
}
else
{
cout << sv << "can not find" << endl;
}
//移除元素
int rv = 2;
mymset.erase(rv);
//再次遍历集合
cout << "set elements: ";
for (const auto& i : myset)
{
cout << i << " ";
}
cout << endl;//5 8
//清空多重集合
mymset.clear();
//检查集合是否为空
if (mymset.empty())
{
cout << "empty";
}
else
{
cout << "not empty";
}
return 0;
}
/////////unordered_set操作和set一样,只是遍历是无序的!(顺序任意)
2,map
map是一种关联容器,用于存储一组键值对(key-value pairs),其中每个键(key)都是唯一(不相同)的
map容器根据键来自动进行排序,并且可以通过键快速查找对应的值
map使用红黑树(red_black tree),数据结构来实现,具有较快的插入,删除,查找操作的时间复杂度o(logN)
定义结构:template <class Key(键),class T(存储的值),class Compare=less<Key>,
class Allocator=allocator<pair<const Key,T>>>class map;
insert(k,v) erase find count(以上均为o(logn))size begin end clear empty (0(1))
lower_bound 返回指向第一个不小于指定键的元素位置
upper_bound ...大于.............................(这两个o(logn))
////////////multimap
允许存储多个具有相同键的键值对
函数:和map差不多(除了后两个没有)
//////////unordered_map
每个键都是唯一的
不会根据键的顺序进行排序,而是使用哈希数组将键映射到存储桶中,使得它具有跟快的时间复杂度,
但不保证顺序,函数:和map差不多(除了后两个没有),平均都为o(1),
但有些最坏可能为o(n),它的时间复杂度是不稳定的,相比之下跟多使用复杂度稳定的map
代码示例:
1,map
int main()
{
//创建并初始化
map<int, string>mymap = { {1,"apple"},{2,"banana"},{3,"orange"} };
//插入元素
mymap.insert(make_pair(4, "grapes"));
//查找和访问元素
cout << mymap[2] << endl;
//遍历并打印map中的元素
for (const auto& p : mymap)
{
cout << "key:" << p.first << ",value:" << p.second << endl;
}
//删除元素
mymap.erase(3);//使用mymap[3]=0,也可,但是count仍为1,因为键值对还在
//判断元素是否存在
if (mymap.count(3) == 0)
{
cout << "key 3 is gone" << endl;
}
else
{
cout << "ok" << endl;
}
//清空map
mymap.clear();
//判断空
if (mymap.empty())
{
cout << "empty" << endl;
}
return 0;
}
2,multimap
int main()
{
//创建并初始化
multimap<int, string>mymultimap = { {1,"apple"},{2,"banana"},{2,"orange"} };//有重复元素
// key:int value:string(和上一个一样)
//插入元素
mymultimap.insert(make_pair(3, "grapes"));
//查找和访问元素
auto range = mymultimap.equal_range(2);
for (auto it = range.first; it != range.second; it++)
{
cout << "key:" << it->first << ",value:" << it->second << endl;
}
/*在 C++ 中,it->first和it->second中的箭头操作符(->)用于访问迭代器所指向的元素的成员。
这是因为迭代器本质上是一种智能指针,它指向容器中的元素。对于multimap,
每个元素都是一个pair<const Key, T>,其中first是键,second是值。
it是一个迭代器,指向multimap中的一个元素(即一个pair对象)。
it->first等价于(*it).first,表示访问该pair的第一个成员(键)。
it->second等价于(*it).second,表示访问该pair的第二个成员(值)。*/
//遍历并打印multimap中的元素
for (const auto& p : mymultimap)
{
cout << "key:" << p.first << ",value:" << p.second << endl;
}
//删除元素
mymultimap.erase(2);
//判断元素是否存在
if (mymultimap.count(2) == 0)
{
cout << "key 2 is gone" << endl;
}
else
{
cout << "ok" << endl;
}
//清空multimap
mymultimap.clear();
//判断空
if (mymultimap.empty())
{
cout << "empty" << endl;
}
return 0;
}
3,unordered_map
int main()//要多写一个头文件!!!<unordered_map>
{
//创建并初始化
unordered_map<string,int>mymap = { {"apple",3},{"banana",5},{"orange",2} };//这里反着来存储了
//key:string value:int
//插入元素
mymap.insert(make_pair("grapes",4));
//查找和访问元素
cout << "value for key 'banana':" << mymap["banana"] << endl;
//遍历并打印
for (const auto& p : mymap)
{
cout << "key:" << p.first << ",value:" << p.second << endl;
}
//删除元素
mymap.erase("orange");
//判断元素是否存在
if (mymap.count("orange") == 0)
{
cout << "key orange is gone" << endl;
}
else
{
cout << "ok" << endl;
}
//清空
mymap.clear();
//判断空
if (mymap.empty())
{
cout << "empty" << endl;
}
return 0;
}
创作不易,大家关注+点赞+收藏,OK?
更多推荐
所有评论(0)