C++~~~set容器、map容器(p57-P69)

一、set容器----构造和赋值

1.set的基本概念:所有元素在插入时自动被排序。

2.本质:set和multiset属于关联事容器,底层结构上用二叉树实现

3.set和multiset的区别

set不允许容器中有重复的元素。

multiset允许容器中有重复的元素。

4.set构造和赋值

(1)功能描述:创建 set 容器并进行赋值。

(2)构造:

cpp 复制代码
set<T> st;//默认构造函数
set(const set &st);//拷贝构造函数

(3)赋值

cpp 复制代码
set& operator=(const set &st);//重载等号操作符

5.代码实现

拷贝构造用括号传入原有的值

cpp 复制代码
// set容器构造和赋值
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;

void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
void test01(){
    set<int> s1;
    //插入数据 只有insert方式
    s1.insert(10);
    s1.insert(40);
    s1.insert(30);
    s1.insert(20);
    s1.insert(30);

    //遍历容器
    //set容器自动去重(不允许插入重复值)、自动排序
    printSet(s1);

    //拷贝构造
    set<int>s2(s1);
    printSet(s2);

    //赋值
    set<int> s3;
    s3=s2;
    printSet(s3);

}
cpp 复制代码
//输出
10 20 30 40 
10 20 30 40 
10 20 30 40 

二、set容器--大小和交换

1.功能描述:统计set容器大小以及交换set容器

2.函数原型:

cpp 复制代码
size();  //返回容器中元素的数目
empty();//判断容器是否为空
swap(st);//交换两个集合容器

3.代码实现:

cpp 复制代码
// set容器大小和交换
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;

void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
void test01(){
    set<int> s1;
    //插入数据 只有insert方式
    s1.insert(10);
    s1.insert(40);
    s1.insert(30);
    s1.insert(20);
    

    //遍历容器
    //set容器自动去重(不允许插入重复值)、自动排序
    printSet(s1);
     
     //判断是否为空
     if(s1.empty())
     {
        cout<<"s1 is empty:"<<endl;
     }else{
        cout<<"s1 is not empty:"<<s1.size()<<endl;
     }
   

}

//交换
void test02()
{
    set<int> s1;
    //插入数据 只有insert方式
    s1.insert(10);
    s1.insert(40);
    s1.insert(30);
    s1.insert(20);
    

    //遍历容器
    //set容器自动去重(不允许插入重复值)、自动排序
    printSet(s1);

    set<int>s2;
      //插入数据 只有insert方式
    s2.insert(100);
    s2.insert(400);
    s2.insert(300);
    s2.insert(200);

    cout<<"before swap:"<<endl;
    printSet(s1);
    printSet(s2);
   
    s1.swap(s2);
    cout<<"after swap:"<<endl;
    printSet(s1);
    printSet(s2);

}
int main(){
test01();
test02();
}
cpp 复制代码
//输出
10 20 30 40 
s1 is not empty:4
10 20 30 40 
before swap:
10 20 30 40 
100 200 300 400 
after swap:
100 200 300 400 
10 20 30 40 

三、set插入和删除

1.功能描述:

set容器进行插入数据和删除数据。

2.函数原型:

cpp 复制代码
insert();//在容器中插入元素
clear();//删除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素

set.erase(elem)的用法类似于list.remove(elem)的用法。

删除某个指定的元素。

3.代码实现

cpp 复制代码
 // set容器--插入和删除
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;
void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}

//set容器插入和删除
void test01()
{
set<int> s1;
//插入的时候,容器就已经完成了排序
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(70);
s1.insert(40);
s1.insert(60);
printSet(s1);

//删除容器的第一个元素
s1.erase(s1.begin());

//删除重载版本
s1.erase(70);
printSet(s1);

//清空的操作
s1.erase(s1.begin(),s1.end());
printSet(s1);

//清空
s1.clear();
printSet(s1);
}
int main(){
test01();
}
cpp 复制代码
//输出
10 20 30 40 60 70 
20 30 40 60 

四、set容器的查找和统计

1.功能描述:对set容器进行查找数据和统计功能。

2.函数原型:

cpp 复制代码
find(key);//查找key是否存在,若存在,返回改键的元素的迭代器;若不存在,返回set.end();
count(key);//统计key的元素个数

3.代码实现:

查找

cpp 复制代码
在这里插入代码片
cpp 复制代码
 // set容器--查找和统计
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;
void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}

//set容器查找和统计
void test01()
{
//查找
set<int> s1;
//插入的时候,容器就已经完成了排序
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(70);
s1.insert(40);
s1.insert(60);
printSet(s1);

set<int>::iterator pos=s1.find(70);
//end()元素上末尾元素的下一个元素,不会和最后一个元素位置重叠
if(pos!=s1.end())
{
    cout<<"find the element:"<<*pos<<endl;
}else{
    cout<<"I can not find the element:"<<endl;
}
// s1.count(0);
// s1.count(60);

}
//统计
void test02()
{
set<int> s1;
//插入的时候,容器就已经完成了排序
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(30);
s1.insert(70);
s1.insert(40);
s1.insert(60);
int num=s1.count(30);
//对于set而言,统计的结果要么是0要么是1.
cout<<"num= "<<num<<endl;
}
int main(){
test01();
// test02();
return 0;
}
cpp 复制代码
//输出
10 20 30 40 60 70 
find the element:70

统计:

cpp 复制代码
 // set容器--查找和统计
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;
void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}

//set容器查找和统计
void test01()
{
//查找
set<int> s1;
//插入的时候,容器就已经完成了排序
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(70);
s1.insert(40);
s1.insert(60);
printSet(s1);

set<int>::iterator pos=s1.find(70);
//end()元素上末尾元素的下一个元素,不会和最后一个元素位置重叠
if(pos!=s1.end())
{
    cout<<"find the element:"<<*pos<<endl;
}else{
    cout<<"I can not find the element:"<<endl;
}
// s1.count(0);
// s1.count(60);

}
//统计
void test02()
{
set<int> s1;
//插入的时候,容器就已经完成了排序
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(30);
s1.insert(70);
s1.insert(40);
s1.insert(60);
int num=s1.count(30);
//对于set而言,统计的结果要么是0要么是1.
cout<<"num= "<<num<<endl;
}
int main(){
// test01();
test02();
return 0;
}
cpp 复制代码
//输出
num= 1

五、set和multiset的区别

1.区别

set不可以插入重读数据,而multiset可以插入重复的数据。

set插入数据的同时会返回插入的结果,表示插入是否成功。

multiset不会检测数据,因此可以插入重复数据。

2.代码实现:

cpp 复制代码
//set容器--set和multiset容器的区别
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;
void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
void test01()
{
    set<int> s;
    pair<set<int>::iterator,bool> ret=s.insert(10);
    //ret.second代表队组的第二个数据bool
    if(ret.second)
    {
        cout<<"first insert is succeed!"<<endl;
    }else{
         cout<<"first insert is not succeed!"<<endl;
    }
    ret=s.insert(10);
     if(ret.second)
    {
        cout<<"second insert is succeed!"<<endl;
    }else{
         cout<<"second insert is not succeed!"<<endl;
    }


}
int main(){
    test01();

}
cpp 复制代码
first insert is succeed!
second insert is not succeed!

multiset的用法

cpp 复制代码
//set容器--set和multiset容器的区别
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;
void printSet(set<int> &s)
{
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
void test01()
{
    set<int> s;
    pair<set<int>::iterator,bool> ret=s.insert(10);
    if(ret.second)
    {
        cout<<"first insert is succeed!"<<endl;
    }else{
         cout<<"first insert is not succeed!"<<endl;
    }
    ret=s.insert(10);
     if(ret.second)
    {
        cout<<"second insert is succeed!"<<endl;
    }else{
         cout<<"second insert is not succeed!"<<endl;
    }

    multiset<int> ms;
    //允许插入重复值
    ms.insert(10);
    ms.insert(10);
    for(multiset<int>::iterator it=ms.begin();it!=ms.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;



}
int main(){
    test01();

}

总结:

如果不允许插入重复的数据用set,如果需要插入重复的数据用multiset。可以右击insert()方法查看定义,查看set和multiset的具体实现。

六、pair使用-pair队组创建

1.功能:成对出现的数据,可以利用队组返回2个数据。

2.两种创建方式:

cpp 复制代码
pair<type,type> p(value1,value2);
pair<type,type> p=make_pair(value1,vaule2);

3.代码实现:

队组可以返回两个数据。

cpp 复制代码
//pair队组
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;

//pair队组的创建
void test01(){
    //第一种方式
    pair<string,int> p("Tom",12);
    cout<<"Name:"<<p.first<<",Age"<<p.second<<endl;

    pair<string,int> p2=make_pair("Jerry",20);
    cout<<"Name:"<<p2.first<<",Age"<<p2.second<<endl;



}
int main(){
    test01();
}
cpp 复制代码
//输出
Name:Tom,Age12
Name:Jerry,Age20

七、set容器--内置类型指定排序规则。

1.set容器默认排序是从小到大。

2.利用仿函数,改变排序规则。

3.例子一:set存放内置数据类型

cpp 复制代码
//set容器排序
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;

class myCompare{
    public:
    //第一个括号代表重载的符号,第一个括号代表重载的符号参数列表
    bool operator()(int v1,int v2)
    {
        //降序
        return v1>v2;
    }
};

void test01(){
    set<int> s1;
    s1.insert(10);
    s1.insert(20);
    s1.insert(50);
    s1.insert(60);
    s1.insert(30);
    cout<<"s1 sort as normal:"<<endl;
    for (set<int>::iterator it=s1.begin();it!=s1.end();it++)
    {
      cout<<*it<<" ";
    }
    cout<<endl;
   
    //我们需要在还没插入数据之前就进行排序规则的制定
    //指定排序规则为从大到小
    set<int,myCompare> s2;
    s2.insert(100);
    s2.insert(20);
    s2.insert(50);
    s2.insert(60);
    s2.insert(30);
   cout<<"s2 sort from big element to small element:"<<endl;
    for(set<int,myCompare>::iterator it=s2.begin();it!=s2.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;


    
}
int main(){
test01();
}
cpp 复制代码
//输出
s1 sort as normal:
10 20 30 50 60 
s2 sort from big element to small element:
100 60 50 30 20 

八、set容器--自定义数据类型指定排序规则

cpp 复制代码
//set容器排序
#include<iostream>
#include<set>
#include<algorithm>//标准算法的头文件
using namespace std;

class Person{
    public:
    Person(string name,int age)
    {
        this->m_Name=name;
        this->m_Age=age;
    }
    string m_Name;
    int m_Age;
};
class comparePerson{
    public:
    //第一个括号是重载符号,第二个括号是形参列表
    bool operator()(const Person p1,const Person p2){
        return p1.m_Age>p2.m_Age;

    }
};
void test(){
    //自定义的数据类型,都会指定排序规则。
    set<Person,comparePerson> s;
    Person p1("PP",12);
    Person p2("lL",18);
    Person p3("oo",10);
    Person p4("uu",30);
    
    
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);

    for(set<Person,comparePerson>::iterator it=s.begin();it!=s.end();it++)
    {
//    cout<<"Name:"<<it->m_Name<<",Age:"<<it->m_Age<<endl;
 cout<<"Name:"<<(*it).m_Name<<",Age:"<<(*it).m_Age<<endl;
    }


}

int main(){
test();
}
cpp 复制代码
Name:uu,Age:30
Name:lL,Age:18
Name:PP,Age:12
Name:oo,Age:10

对于自定义的数据类型,set必须指定排序规则才可以插入数据。

九、map/multimap容器

1.map的基本概念

(1)map中所有元素都是pair。

(2)pair中第一个元素是key(键值),起到索引作用。第二个元素为value(实际值)。

(3)所有元素会根据元素的键值自动排序。

2.本质

map/multimap属于关联式容器,底层结构是用二叉树实现。

3.优点:

可以根据key值快速找到value值。

4.map和multimap的区别

这两者的value值可以重复。

(1)map不允许容器中有重复的key值元素。

(2)multimap允许容器中有重复的key值元素。

5.map构造和赋值

1.功能描述:对map容器进行构造和赋值操作

2.函数原型:

cpp 复制代码
//构造
map<T1,T2>mp;//map默认构造函数
map(const map &map);//拷贝构造函数
//赋值
map &operator=(const map &map);//重载等号操作符

3.代码实现

map是按key进行排序,而不是按照value排序。

cpp 复制代码
//map容器的构造和赋值
#include<iostream>
using namespace std;
#include<map>
void printMap(map<int,int>&m){
    for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
    {
        cout<<"Key="<<(*it).first<<",Value="<<(*it).second<<endl;
    }

}
void test(){
//创建map容器
map<int ,int >m;
m.insert(pair<int,int>(1,10));
m.insert(pair<int,int>(2,30));
m.insert(pair<int,int>(3,40));
m.insert(pair<int,int>(4,20));

printMap(m);
}
int main(){
    test();
}
cpp 复制代码
//输出
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20

拷贝构造和赋值操作

cpp 复制代码
//map容器的构造和赋值
#include<iostream>
using namespace std;
#include<map>
void printMap(map<int,int>&m){
    for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
    {
        cout<<"Key="<<(*it).first<<",Value="<<(*it).second<<endl;
    }

}
void test(){
//创建map容器
map<int ,int >m;
m.insert(pair<int,int>(1,10));
m.insert(pair<int,int>(2,30));
m.insert(pair<int,int>(3,40));
m.insert(pair<int,int>(4,20));

printMap(m);


cout<<"Copy constructor:"<<endl;

//拷贝构造
map<int,int>m2(m);
printMap(m2);

//赋值
cout<<"Operator operation:"<<endl;
map<int,int> m3;
m3=m2;
printMap(m2);
}
int main(){
    test();
}
cpp 复制代码
//输出
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Copy constructor:
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Operator operation:
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20

总结:map中所有元素都是成对出现,插入数据的时候要使用对组。

十、map容器的大小和交换

1.功能描述:统计map容器大小以及交换map容器。

2.函数原型:

cpp 复制代码
size();//返回容器中元素的数组
empty();//判断容器是否为空
swap(st);//交换两个集合容器

3.代码实现:

cpp 复制代码
//map容器的大小和交换
#include<iostream>
using namespace std;
#include<map>
void printMap(map<int,int>&m){
    for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
    {
        cout<<"Key="<<(*it).first<<",Value="<<(*it).second<<endl;
    }

}
void test(){
//创建map容器
map<int ,int >m;
m.insert(pair<int,int>(1,10));
m.insert(pair<int,int>(2,30));
m.insert(pair<int,int>(3,40));
m.insert(pair<int,int>(4,20));

printMap(m);

if(m.empty())
{
    cout<<"Map is empty:"<<endl;
}else{

cout<<"Map is empty and map size is:"<<m.size()<<endl;

}
}

void test02(){
    //创建map容器1
map<int ,int >m;
m.insert(pair<int,int>(1,10));
m.insert(pair<int,int>(2,30));
m.insert(pair<int,int>(3,40));
m.insert(pair<int,int>(4,20));

  //创建map容器2
map<int ,int >m2;
m2.insert(pair<int,int>(1,100));
m2.insert(pair<int,int>(2,300));
m2.insert(pair<int,int>(3,400));
m2.insert(pair<int,int>(4,200));

cout<<"Before swap m1 is:"<<endl;
printMap(m);
cout<<"Before swap m2 is:"<<endl;
printMap(m2);

m.swap(m2);
cout<<"After swap m1 is:"<<endl;
printMap(m);
cout<<"After swap m2 is:"<<endl;
printMap(m2);
}

int main(){
    test();
    test02();
}
cpp 复制代码
//输出
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Map is empty and map size is:4
Before swap m1 is:
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Before swap m2 is:
Key=1,Value=100
Key=2,Value=300
Key=3,Value=400
Key=4,Value=200
After swap m1 is:
Key=1,Value=100
Key=2,Value=300
Key=3,Value=400
Key=4,Value=200
After swap m2 is:
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20

十一、map容器的插入和删除。

1.功能描述:map容器进行插入数据和删除数据。

2.函数原型:

cpp 复制代码
insert(elem);//在容器中插入元素
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
erase(key);//删除容器中值为key的元素

3.代码实现:

cpp 复制代码
//map容器的大小和交换
#include<iostream>
using namespace std;
#include<map>
void printMap(map<int,int>&m){
    for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
    {
        cout<<"Key="<<(*it).first<<",Value="<<(*it).second<<endl;
    }
    cout<<endl;

}
void test(){
//创建map容器
map<int ,int >m;

//插入,第一种
m.insert(pair<int,int>(1,10));
m.insert(pair<int,int>(2,30));
m.insert(pair<int,int>(3,40));
m.insert(pair<int,int>(4,20));



//插入,第二种方式
m.insert(make_pair(5,100));

//插入,第三种方式
m.insert(map<int,int>::value_type(6,200));

//插入,第四种方式
m[7]=300;

//插入,第四种方式的反例,会导致值为0.
//但是可以利用key访问到value,前提是这个队组元素存在在map中
//cout<<m[8]<<endl;
cout<<"the seven element value is:"<<m[7]<<endl;

printMap(m);

//删除
cout<<"After delete the first element:"<<endl;
m.erase(m.begin());
printMap(m);

//按照key删除
cout<<"After delete the second element:"<<endl;
m.erase(2);
printMap(m);

//按照区间删除,类似清空
cout<<"After delete all element:"<<endl;
m.erase(m.begin(),m.end());
printMap(m);

//清空操作
cout<<"After clear all element:"<<endl;
m.clear();
printMap(m);

}


int main(){
    test();  
}
cpp 复制代码
//输出
the seven element value is:300
Key=1,Value=10
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Key=5,Value=100
Key=6,Value=200
Key=7,Value=300

After delete the first element:
Key=2,Value=30
Key=3,Value=40
Key=4,Value=20
Key=5,Value=100
Key=6,Value=200
Key=7,Value=300

After delete the second element:
Key=3,Value=40
Key=4,Value=20
Key=5,Value=100
Key=6,Value=200
Key=7,Value=300

After delete all element:

After clear all element:
相关推荐
qeen871 小时前
【数据结构】哈希表的C++实现与封装
数据结构·c++·散列表·哈希表
脉动数据行情12 小时前
Java SpringBoot 对接知名台股 TWSE|批量采集上市股票行情实践
java·开发语言·spring boot
IKUN家族2 小时前
SpringBoot日志
java·开发语言
迷迭香yy2 小时前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源
格林威3 小时前
C#图像快速剪切:使用OpenCvSharp和Halcon优化图像剪切和CPU占用
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
知识分享小能手3 小时前
概理论与数理统计学习教程,从入门到精通,在数理统计中应用R软件(22)
开发语言·学习·r语言
乐观勇敢坚强的老彭3 小时前
C++信奥GESP四级的常见题型和解题模板速查表
开发语言·c++
denggun123453 小时前
信号量(DispatchSemaphore vs AsyncSemaphore)、swift协作式线程池 and python信号量
开发语言·python·swift
lisw053 小时前
计算与科学哲学(Philosophy of Computing and Science)
java·开发语言·人工智能