你什么都没有,却还为我的梦加油————set 容器的简单用法

1.set容器的定义

set<typename > a; typename 可以是很多数据类型的名称。

最常见的就是:

整数类型:(本蒟蒻只会用这个,其他的不太了解,等以后再更新其他的用法)

set<int> a.

2.set容器迭代器:(理解为指针)

  (1).利用迭代器容器遍历容器内的元素

set<int> :: iterator it ,我们可以用 迭代器(指针)it来访问容器内的元素。

比如我们要遍历set容器内的所有元素:

for (it = a.begin(); it != a.end();it++)
    cout << *it << ' ';

我们看这个迭代器的定义,它里面是没有包含任何set容器的名称,也就是说, it可以属于任何set容器,即a用完了可以给b用。 

 for (int i = 10; i >= 0; i--)
     a.insert(i);
 for (it = a.begin(); it != a.end(); it++)
     b.insert(*it);
 for (it = b.begin(); it != b.end(); it++)
     cout << *it << ' ';

下面是几种错误的迭代器改变方式:

为什么呢,经过我查找资料,发现set容器的迭代器是一种叫“双向迭代器”的东西。

(2).常见迭代器的类型有哪些:

    前向迭代器:

  1.       迭代器只支持自增操作:it++ ,++it ,并且it  可以被复制或赋值,仅能用 == 和 != 运算符进行比较。此外,两个正向迭代器可以互相赋值。

    双向迭代器:(set)

  1. 双向迭代器具有正向迭代器的全部功能,除此之外,假设 p 是一个双向迭代器,则还可以进行 --p 或者 p-- 操作。

    随机访问迭代器(可以理解为数组下标):(vector)

  1. 随机访问迭代器具有双向迭代器的全部功能。除此之外,假设 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下操作:

    • p+=i:使得 p 往后移动 i 个元素。
    • p-=i:使得 p 往前移动 i 个元素。
    • p+i:返回 p 后面第 i 个元素的迭代器。
    • p-i:返回 p 前面第 i 个元素的迭代器。
    • 此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。另外,表达式 p2-p1 也是有定义的,其返回值表示 p2 所指向元素和 p1 所指向元素的序号之差(也可以说是 p2 和 p1 之间的元素个数减一)。

3.set容器的常用函数:

   (1).   name.insert()

              这里的name指的是你要将括号里的内容插入到哪个set容器里面,括号里面是value,一共具体的值,不能是迭代器本身。*it就是迭代器指向的值。

返回值是一个pair对

pair.first是   这个数插入的位置,也就是一个迭代器。

pair.second是一个bool值,代表是否插入成功。

所以如果我们要查看是否插入成功只需要访问 insert().second 即可

时间复杂度是O(n),n为元素个数

 for (int i = 10; i >= 0; i--)
     a.insert(i);

 

(2) name.find( )

           查找某个元素是否在set容器中,如果在,返回该元素的迭代器。如果没在,它会返回到最后一个位置,也就是name.end(). 下面是返回的参数

并且name.find()函数的时间复杂度是O(logn)

 b容器内元素是0~10

 b.find(5);     如果找得到会返回该元素的迭代器。所以我们可以直接输出*b,find()
 cout << *b.find(5)<<endl;
 b.find(11);
 if(b.find(11)==b.end())
 cout << *(--b.end());

    并且我们是不能返回*b.end(),即b.end()的值,因为它是一块未知的地方。(本蒟蒻的理解)

(3)name.begin() 和 name.end()

         返回的是set容器第一个元素的迭代器,和最后一个元素的后面一个位置(这个位置是没有值的)的迭代器。

         因为set迭代器是双向迭代器,只能进行赋值比较,即== 和!= 无法进行< or > or >=  or <=这种比较运算符。(上面讲了)

所以我们遍历的每个元素时正确的做法是:

​
 for (it = a.begin(); it != a.end(); it++)
     b.insert(*it);

​

错误的做法是:(前往不可以比较大小)

 for (it = a.begin(); it < a.end(); it++)
     b.insert(*it);

  (4) name.size()

     返回一个value,是集合内元素的个数,不需要任何参数,返回的是集合中的元素个数

 for (it = a.begin(); it != a.end(); it++)
     b.insert(*it);
 cout << b.size();

  (5) name.erase()

    删除集合内的元素,或者某个区间内的元素。

    所以括号内的参数可以是一个具体的值。

    可以是迭代器,也可以是两个迭代器来表示区间。我们要找区间,就可以用上面讲过的 

    name.find()函数来找具体的区间(注意:删除区间是左闭右开的)

当集合中有这个元素,删除成功,返回1,当没有这个元素,删除失败,返回0

   时间复杂度是  O(first—last)

    

int main()
{
	set<int> a;
	set<int> ::iterator it;
	for (int i = 1; i <= 100; i++)
	{
		a.insert(i);
	}
	auto ig = a.find(20);
	auto ik = a.find(51);
	a.erase(ig, ik);
	for (it = a.begin(); it != a.end(); it++)
		cout << *it << ' ';
}

     

(6)name.count()函数

是用来查找集合中某个元素出现的次数,由于集合中每个元素只能出现一次,所以这个函数的返回值是 0 or 1

int main()
{
	set<int> a;
	set<int> ::iterator it;
	for (int i = 1; i <= 100; i++)
	{
		a.insert(i);
	}
	cout<<a.count(99);

}

(7)name.clear()

   清除集合中所有元素。时间复杂度是O(N) 。括号内没有参数

   

int main()
{
	set<int> a;
	set<int> ::iterator it;
	for (int i = 1; i <= 100; i++)
	{
		a.insert(i);
	}
	
	cout << a.size() << endl;
	a.clear();
	cout << a.size();
}

 (8)set.lower_bound 
二分查找一个数,返回参数如下

可以看到返回的也是一个迭代器,只不过和find函数有所不同的是,

如果集合里面没有这个数字,我们就返回第一个大于等于这个数的迭代器,

倘若,查找的数字比现在集合中的所有数字都大,那么返回的就是end(); 

好了本期内容到此结束谢谢观看

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值