C++ | 集合 set

一.集合

是由若干个不相同的元素组成的,如 \(\{1,2,3\}\),可用 set 表示集合
需要加 #include<set>
支持 #include<bits/stdc++.h>

1.定义方法:

set <T> s;
set <int> aa;
set <string> bbb;

2.插入元素

insert(*****);

set <int> s;
s.insert(1);

插入相同元素时,不会做修改也不会报错

3.删除元素

set <int> s;
s.insert(1);
s.erase(1);//有 1 ,删除它
s.erase(1);//没有,不理这句话

4.判断元素是否存在

set <int> s;
s.insert(1);
if(s.count(1))//判断1存在吗?
{
    cout<<"1";
}

运行结果:1

5.元素的遍历(每一个元素)

begin()集合的开始
end()集合的末尾
遍历代码:(输出的顺序:从小到大或字典序)

set <int> s;
for(set<int>::iterator i=s.begin();i!=s.end();i++)
{
    cout<<*i<<endl;
//       迭代器
}

迭代器可以放在for循环之外

set <int> s;
set <int>::iterator i;
for(i=s.begin();i!=s.end();i++)
{
    cout<<*i<<endl;
//       迭代器
}

6.获取元素的个数

set <int> s;
int num=s.size();

7.集合的清空,同时释放内存

set <int> s;
s.clear();

8.时间复杂度

insert \(O(\log(n))\)
erase \(O(\log(n))\)
count \(O(\log(n))\)
size \(O(1)\)
clear \(O(n)\)

9.运算符重载

由于set是自带排序的,但自定义的结构体系统不会排序
这时就需要一个像sortcmp的东西,叫运算符重载
这个代码重载了小于号

struct Node
{
    int x,y;
    bool operator<(const Node &rhs) const     //当两边都是Node类型的变量且中间是小于号时
    {
        //谁小谁就靠前
        if(x=rhs.x) y<rhs.y;
        else return x<rhs.x;
    }
};

实践:用结构体和集合,输入n个点,去重输出。

#include<bits/stdc++.h>
using namespace std;
struct Point
{
	int x,y;
	bool operator<(const Point &rhs) const
	{
		if(x==rhs.x)return y<rhs.y;
		else return x<rhs.x;
	}
};
int main()
{
	int n;//n个点
	set <Point> v;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		Point temp;//每一个点
		cin>>temp.x>>temp.y;
		v.insert(temp);//往集合里加 
	} 
	//遍历
	for(set<Point>::iterator i=v.begin();i!=v.end();i++) 
	{
		//指针
		cout<<i->x<<" "<<i->y<<endl;
                //等价于 *(it).x 
	}
	return 0;
}

10.两个实用函数

\(2.3\)

二.多重集合

也在头文件set中。一个元素可以存多次。

1.定义、插入、计数和删除

multiset <int> ms;
ms.insert(5);//{5}
ms.insert(2);//{2,5}
ms.erase(5);//{2}
ms.erase(1);//{2}
ms.insert(6);//{2,6}
ms.insert(6);//{2,6,6}
ms.erase(6);//{2,6}
int w=ms.count(6);//6的个数,是1

2.仅删除一个

上面的erase会把集合中所有的元素都删除,可用find只删除一个。
find(x)是迭代器,表示集合中第一次出现x的位置

multiset <int> ms;
for(int i=1;i<=3;i++)ms.insert(5);//{5,5,5}
ms.erase(ms.find(5));//删除第一个元素
cout<<ms.count(5);//输出2

3.两个实用函数、删除与大小

lower_bound(x)返回第一个大于等于x的元素的迭代器
upper_bound(x)返回第一个大于x的元素的迭代器

实践:

multiset <int> ms;
ms.insert(4);
ms.insert(5);
ms.insert(5);
ms.insert(7);
cout<<*ms.lower_bound(4)<<endl;//4
cout<<*ms.upper_bound(4)<<endl;//5
cout<<*ms.lower_bound(9)<<endl;//没有,有4个元素,4
//如果要找位置,就继续用迭代器
multiset<int>::iterator i=ms.lower_bound(4);//也可以写upper_bound(4)
if(i==ms.end())cout<<"-1";//这个就是找不到,没有
cout<<*i<<endl;//具体值
ms.erase(i);//删除迭代器,不是删除 *i
cout<<ms.size();//大小,3

三.映射表

指两个集合间的关系,如姓名集合\(\{"TOM","JONE","MARY"\}\)和班级集合\(\{1,2\}\)可以有:

\(class("TOM")=1\)
\(class("JONE")=2\)
\(class("MARY")=1\)

我们称姓名集合为关键字集合\((key)\),班级集合为值集合\((value)\)
map来存储映射表

1.引用库

引用以下两种之一即可

#include<map>
#include<bits/stdc++.h>

2.构造映射

//map <T1,T2> m;
map <string,int> m;
//  关键字  值

3.插入映射

//接着上面的
m["TOM"]=1;//{"TOM"->1}
//也就可以输出
cout<<m["TOM"]<<endl;
//如果重复赋值将会覆盖
//赋值这样也可以:
m.insert(make_pair("TOM",1));
m["TOM"]=2;//覆盖
m["TOM"]++;//也是覆盖,+1
m["JANE"]++;//直接赋值为1

4.判断关键字是否存在

if(m.count("TOM"))cout<<1;

5.遍历(从小到大或字典序)

for(map<string,int>::iterator i=m.begin();i!=m.end();i++)
    cout<<i->first<<" "<<i->second<<endl;
    //       关键字         对应的值
    // 也可以是 (*it).first

6.清空并释放内存

m.clear();

7.时间复杂度

insert \(O(\log(n))\)
count \(O(\log(n))\)
size \(O(1)\)
clear \(O(n)\)

三.二维map

1.map套用set

举个例子:map<int,set<string>> s;
// 班级 姓名集合
对于2班和TOM,就可以

s[2].insert("TOM");//TOM加入2班
if(s[2].count("TOM"))cout<<1;//查询TOM是否在2班
s[2].erase("TOM");//2班踢出TOM

遍历

for(map<int,set<string> >::iterator i=m.begin();i!=m.end();i++)
{
	for(set<string>::iterator i2=(i->second).begin();i2!=(i->second).end();i2++)
	{
		cout<<*i2<<" is in class "<<i->first<<endl;
	}
}

2.map套用map

举个例子:map<int,map<string,int>> s;
//针对重名 班级 姓名 次数
对于2班和TOM,就可以

s[2]["TOM"]++;//新来了一个叫TOM的人
cout<<s[2]["TOM"]++;//现在有多少个叫TOM的人

遍历:

for(map<int,map<string,int>>::iterator i1=s.begin();i1!=s.end;i1++)
{
    for(map<string,int>::iterator i2=i1->second.begin();i2!=i1->second.end();i2++)
        cout<<"There are "<<i2->second<<" people named "<<i2->first<<" in class "<<i1->first<<endl;
}

四.补充的杂七杂八 \(STL\)

1.小写转换

string s;
cin>>s;
s=tolower(word[i]);
posted @ 2020-03-10 20:30  superter  阅读(616)  评论(0编辑  收藏  举报