只是一篇超详细的c++ set用法总结罢了

16 篇文章 0 订阅

set是STL中一种标准关联容器,所谓关联容器,就是其元素存放位置并不连续,而是按照一定的关系存放的(比如说红黑树,哈希表),与此对应的是顺序容器,顺序容器元素按照顺序存放(如vector,list)。

set底层使用平衡的搜索树——红黑树实现。使用时需要包含头文件<set>。如果大家对红黑树了解,那么对set中的规则就很容易理解,如果不了解,先记下来也行。set的插入和查找的时间复杂度为O(logn),且插入之后元素有序排列。set不支持通过迭代器修改元素,因为如果元素被修改,那么红黑树就可能被打乱。

set在插入数据时会自动对数据进行排序,set中的元素不能重复。

1.成员函数汇总

 以下用set<int>myset来演示用法
//迭代器
(1)myset.begin()//指向myset第一个元素的迭代器
(2)myset.end()//指向myset最后一个元素之后一个位置的迭代器
(3)myset.rbegin()//指向myset最后一个元素的迭代器,注意不等于end()
(4)myset.rend()//指向myset第一个元素之前一个位置的迭代器,注意不等于begin()

//元素调整
(5)myset.insert(4)//向myset里插入元素4,返回值pair<iterator,bool>,第一位是指向4的迭代器,第二位是否插入成功
(6)myset.insert (const_iterator position, 4);//如果知道4的位置position直接插入效率更高
(7)myset.insert (InputIterator first, InputIterator last);//插入[first,last)的元素
(8)myset.emplace (4)//插入4,返回值pair<iterator,bool>,与insert意义相同
(9)myset.erase(const_iterator position);//删除position位置元素,返回position
(10)myset.erase (4);//若4之前存在返回1,否则返回0
(11)myset.erase (const_iterator first, const_iterator last);//删除[first,last)位置元素,返回last
(12)myset.swap(x)//将myset与x中的元素交换,实际上交换的是指针
(13)myset.size()//返回容器中元素个数
(14)myset.clear()//清空myset

//查找计数
(15)myset.find(4)//查找4这个元素,找到返回此元素迭代器,没有找到返回myset.end()
(16)myset.lower_bound(4)//查找第一个大于等于4的元素,返回此元素迭代器,未找到返回myset.end()
(17)myset.upper_bound(4)//查找第一个大于4的元素,返回此元素迭代器,未找到返回myset.end()
(18)equal_range(4)//返回对组(a,b),a为myset.lower_bound(4),b为myset.upper_bound(4)
(19)myset.count(4)//对4进行计数,如果存在返回1,不存在返回0

//容量有关
(20)myset.empty()//如果myset为空返回true,否则返回false
(21)myset.max_size()//返回容器能容纳的最多元素个数,这是容器可以达到的最大潜在大小,但绝不能保证容器能够达到该大小

//其他
(22)myset.key_comp()//返回容器的比较函数,如果没有自定义就是默认比较函数(从小到大),比较函数类型为std::set<int>::key_compare
                    //很少使用,具体用法可参考官方的帮助文档
(23)myset.value_comp()//同key_comp()

2.构造函数

#include <iostream>
#include <set>

int main ()
{
  int myints[]={ 12,82,37,64,15 };//直接赋值
  std::set<int> first (myints,myints+5);   // 用迭代器赋值
  std::set<int> second;                    // 创建空set

  second = first;                          // set给set赋值
  first = std::set<int>();                 // first为空

  std::cout << "Size of first: " << int (first.size()) << '\n';
  std::cout << "Size of second: " << int (second.size()) << '\n';
  return 0;
}

输出:

Size of first: 0
Size of second: 5

3.自定义排序

set默认为从小到大排序,当我们需要更改排序方式或者我们插入的数据没有默认排序方式时,我们需要进行自定义排序。

struct cmp {
	bool operator () (const int &a, const int &b) {
		return a > b;//从大到小排序
	}
};

int main()
{
	set<int,cmp>myset = { 2,4,1,4,6 };
	for (auto x : myset)cout << x << " ";//访问myset中每一个元素
}

输出为:6 4 2 1

没有默认排序方式时的自定义排序,比如set里面存放的是结构体,那么如果不自定义排序方式,结构体是无法插入到set中的:

struct st {
	int k;
	string s;
};

struct cmp {
	bool operator () (const st &a, const st &b) {
		return a.k > b.k;
	}
};

int main()
{
	st s,s1,s2;
	s.k = 3;
	s.s = "sss";
	s2.k = 2;
	s2.s = "aaa";
	s1.k = 1;
	s1.s = "bbb";
	set<st, cmp>myset = {s,s1,s2};
	for (auto x : myset)cout << x.k << " " << x.k << endl;
}

输出:
3 3
2 2
1 1

4.非成员函数重载

1.重载运算符,需要元素类型和比较函数相同。

int main()
{
	std::set<int> foo = { 10,40 };
	std::set<int> bar = { 20,30 };

	// foo ({10,40}) vs bar ({20,30}):
	if (foo == bar) std::cout << "foo and bar are equal\n";
	if (foo != bar) std::cout << "foo and bar are not equal\n";
	if (foo < bar) std::cout << "foo is less than bar\n";
	if (foo > bar) std::cout << "foo is greater than bar\n";
	if (foo <= bar) std::cout << "foo is less than or equal to bar\n";
	if (foo >= bar) std::cout << "foo is greater than or equal to bar\n";

	return 0;
}

输出:
foo and bar are not equal
foo is less than bar
foo is less than or equal to bar 

2.还有很多STL里面的通用函数,比如<algorithm>里面的swap(),upper_bound(),lower_bound()等等,有的在set成员函数里也有同样功能的函数,使用哪种都可以。

5.注意事项

1.不能通过set的迭代器改变元素值,毕竟改变值之后红黑树就被打乱了。
2.不能通过[ ]的方式访问元素
3.其迭代器没有+1,-1的操作,但是有++,--操作,大家可以自己去试一试。
4.set中元素不能重复,与此相对应的multiset中的元素可以重复,multiset和set操作基本一样。
5.除此之外还有unordered_set和unordered_multiset,为set和multiset的无序版,使用时要包含头文件<unordered_set>,其底层为哈希表。

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值