C++之STL

C++之STL

STL概述

STL(Standard Template Library,标准模板库)
STL的6大组件:容器、算法、迭代器、适配器、仿函数、空间配置
容器:存放数据
算法:操作数据
迭代器:算法 通过迭代器 操作容器
适配器:为算法 提供更多的接口
仿函数:为算法 提供策略
空间配置:为算法、容器提供动态空间
算法分类:质变算法、非质变算法
质变算法:会更改容器的值(拷贝,替换,删除等等)
非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等

容器

string容器

1、stirng的构造函数和赋值

1、stirng的构造函数:
 string();//创建一个空的字符串 例如: string str;
 string(const string& str);//使用一个string对象初始化另一个string对象
 string(const char* s);//使用字符串s初始化
 string(int n, char c);//使用n个字符c初始化 v


2、string基本赋值操作
 string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
 string& operator=(const string &s);//把字符串s赋给当前的字符串
 string& operator=(char c);//字符赋值给当前的字符串
 string& assign(const char *s);//把字符串s赋给当前的字符串
 string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
 string& assign(const string &s);//把字符串s赋给当前字符串
 string& assign(int n, char c);//用n个字符c赋给当前字符串
 string& assign(const string &s, int start, int n);//将s从start开始n个字符赋值给字符串

eg:

int main()
{
    //string(const char* s);//使用字符串s初始化
    string str("hello");
    //string(const string& str);//使用一个string对象初始化另一个string对象
    string str2=string(str);
    //string(int n, char c);//使用n个字符c初始化 v
    string h=string(5,'H');//HHHHH

    // string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串

    str="world";

    //string& operator=(const string &s);//把字符串s赋给当前的字符串
    str=str2;
    //string& operator=(char c);//字符赋值给当前的字符串
    str='A';
    //string& assign(const char *s);//把字符串s赋给当前的字符串
    str.assign("hello");
    //string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
    str.assign("hello",3);
    //string& assign(const string &s);//把字符串s赋给当前字符串
    str.assign(str2);
    //string& assign(int n, char c);//用n个字符c赋给当前字符串
    h.assign(5,'H');
    //string& assign(const string &s, int start, int n);//将s从start开始n个字符赋值给字符串
    str.assign(str2,0,5);

    return 0;
}

2、string存取字符操作

 char& operator[](int n);//通过[]方式取字符
 char& at(int n);//通过at方法获取字符
    string str("hello");
    cout<<str[1]<<endl;//e
    cout<<str.at(1)<<endl;//e

两者区别:[] 越界不会抛出异常 ,at越界会抛出异常

try
 {
 //str1[1000]='A';
 str1.at(1000)='A';
 }
 catch(exception &e)
{
 cout<<"捕获到异常:"<<e.what()<<endl;
}

3、string拼接操作

 string& operator+=(const string& str);//重载+=操作符
 string& operator+=(const char* str);//重载+=操作符
 string& operator+=(const char c);//重载+=操作符
 string& append(const char *s);//把字符串s连接到当前字符串结尾
 string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
 string& append(const string &s);//同operator+=()
 string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
 string& append(int n, char c);//在当前字符串结尾添加n个字符c

4、string查找和替换

int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
 int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
 int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
 int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
 int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从pos开始查找
 int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从pos开始查找
 int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后一次位置
 int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
 
 string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
 string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为字符串s

5、string比较操作

> < == != 运算符 可用
 /*
 compare函数在>时返回 1,<时返回 ‐1,==时返回 0。
 比较区分大小写,比较时参考字典顺序,排越前面的越小。
 大写的A比小写的a小。
 */
 int compare(const string &s) const;//与字符串s比较
 int compare(const char *s) const;//与字符串s比较

6、提取string子串

string substr(int pos = 0, int n = npos) const;
//返回由pos开始的n个字符组成的字符串  pos是起始位置,n是长度
void test06()
 {
 string str1="hehehe:hahaha:xixixi:lalala";
 int pos = 0;
 while(1)
 {
 int ret = str1.find(":", pos);
 string tmp = str1.substr(pos, ret‐pos);
 cout<<tmp<<endl;

 pos = ret+1;
 }
 }

7、string插入和删除操作

string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串string& insert(int pos, int n, char c);//在指定位置插入n个字符c

string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
#include <iostream>
#include<string>
using namespace std;


int main()
{
    string str="hello";
    str.insert(2,"###");//he###llo
    cout<<str<<endl;
    str.erase(2,3);//hello
    cout<<str<<endl;
    return 0;
}

8、 string和c-style字符串转换

    string str="hello"; //char *  =>  string (认支持)
    char *h=str;        //string => char * 报错

string转换成char* 必须使用成员函数c_str(c_str的返回值是const char *)

   
    char *h=(char *)str.c_str();//强转,将const char *转成char*
    
    char *h2=const_cast<char *>(str.c_str());
vector容器

单端动态数组容器
在这里插入图片描述

push_back尾部插入元素、pop_back尾部删除元素
front()头元素、back()尾元素
begin()得到的是 容器的 起始迭代器(首元素的位置)
end() 得到的是 结束迭代器(尾元素的下一个元素位置

必须包含头文件:#include<vector>

#include <iostream>
#include<vector>
using namespace std;


int main()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);

    //遍历容器
    vector<int>::iterator it=v1.begin();//定义一个迭代器iterator 保存是元素的位置
    for(;it!=v1.end();it++){
        cout<<*it<<endl;
    }
    return 0;
}

vector的未雨绸缪机制:

#include <iostream>
#include<vector>
using namespace std;

int main()
{
    vector<int> v;
    cout<<"容量:"<<v.capacity()<<" "<<"大小:"<<v.size()<<endl;
    vector<int>::iterator it;
    int i=0;
    int count=0;
    for(i=1;i<=1000;i++){
        v.push_back(1);
        if(it!=v.begin()){
            count++;
            cout<<"第"<<count<<"开辟空间,容量为:"<<v.capacity()<<endl;
            it=v.begin();
        }
    }
    return 0;
}

容量:0 大小:0
第1开辟空间,容量为:1
第2开辟空间,容量为:2
第3开辟空间,容量为:4
第4开辟空间,容量为:8
第5开辟空间,容量为:16
第6开辟空间,容量为:32
第7开辟空间,容量为:64
第8开辟空间,容量为:128
第9开辟空间,容量为:256
第10开辟空间,容量为:512
第11开辟空间,容量为:1024

vector API

 vector构造函数:
 vector<T> v; //采用模板实现类实现,默认构造函数
 vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
 vector(n, elem);//构造函数将n个elem拷贝给本身。
 vector(const vector &vec);//拷贝构造函数
vector常用赋值操作
 assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
 assign(n, elem);//将n个elem拷贝赋值给本身。
 vector& operator=(const vector &vec);//重载等号操作符
 swap(vec);// 将vec与本身的元素互换。
vector大小操作:
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值0填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

capacity();//容器的容量
reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问
vector数据存取操作
at(int idx); //返回索引idx所指的数据,如果idx越界,抛out_of_range异常。
operator[];//返回索引idx所指的数据,越界时,运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素
vector插入和删除操作
insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele.
push_back(ele); //尾部插入元素ele
pop_back();//删除最后一个元素
erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();

巧用swap收缩空间:

int main()
{
    vector<int> v1;
    v1.reserve(1000);//预留1000个空间
    v1.assign(5,10);//存入5个10
    cout<<"大小:"<<v1.size()<<"容量:"<<v1.capacity()<<endl;
    vector<int>(v1).swap(v1);//拷贝构造一个和v1一样的匿名vector,再和v1交换
    cout<<"大小:"<<v1.size()<<"容量:"<<v1.capacity()<<endl;


    return 0;
}
大小:5容量:1000
大小:5容量:5

容器嵌套容器

int main()
{

    vector<int> v1(5,10);
     vector<int> v2(5,100);
    vector<int> v3(5,1000);
    vector<vector<int>> v;
    v.push_back(v1);
    v.push_back(v2);
    v.push_back(v3);
//遍历
          vector<vector<int>>::iterator mit;
          for(mit=v.begin();mit!=v.end();mit++){
              vector<int>::iterator it;
              for(it=(*mit).begin();it!=(*mit).end();it++){
                  cout<<*it<<" ";
              }
              cout<<endl;
          }

    return 0;
}

打印结果

10 10 10 10 10
100 100 100 100 100
1000 1000 1000 1000 1000

使用算法 对 vector容器排序

需要引入算法的头文件

#include<algorithm>
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;


void printVectorInt(vector<int> v){
    vector<int>::iterator it;
    for(it=v.begin();it!=v.end();it++){
        cout<<*it<<endl;
    }
}

bool myCompare(int a,int  b){
    return a<b;
}

int main()
{

     vector<int> v1;
     v1.push_back(20);
     v1.push_back(60);
     v1.push_back(30);
     v1.push_back(50);
     v1.push_back(40);
     v1.push_back(10);
     printVectorInt(v1);
     cout<<"------------"<<endl;
     // sort(v1.begin(),v1.end());
     //sort(v1.begin(),v1.end(),greater<int>());//greater从大到小排序
     sort(v1.begin(),v1.end(),myCompare);
     printVectorInt(v1);
    return 0;
}

vector存放自定义数据类型

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Person{

    friend void printVectorPerson(vector<Person> v);
    friend bool myCompare(const Person &ob1,const Person &ob2);
private:
    int num;
    string name;
    float score;

public:
    Person(){}
    Person(int num,string name,float score){
        this->num=num;
        this->name=name;
        this->score=score;
    }
    //重载小于号
    bool operator<(const Person &p){
        return this->num<p.num;
    }

};
void printVectorPerson(vector<Person> v){
    vector<Person>::iterator it;
    for(it=v.begin();it!=v.end();it++){
        cout<<(*it).num<<" "<<(*it).name<<" "<<(*it).score<<endl;
    }
}

bool myCompare(const Person &ob1,const Person &ob2){
    return ob1.num>ob2.num;
}

int main()
{

     vector<Person> v;
     v.push_back(Person(100, "lucy", 88.8f));
     v.push_back(Person(103, "bob", 99.8f));
     v.push_back(Person(103, "tom", 77.8f));
     v.push_back(Person(103, "德玛", 88.8f));
     v.push_back(Person(101, "小法", 66.8f));
     printVectorPerson(v);
     cout<<"------------"<<endl;
     sort(v.begin(),v.end());
     printVectorPerson(v);
     cout<<"------------"<<endl;
     sort(v.begin(),v.end(),myCompare);
     printVectorPerson(v);
    return 0;
}

100 lucy 88.8
103 bob 99.8
103 tom 77.8
103 德玛 88.8
101 小法 66.8
------------
100 lucy 88.8
101 小法 66.8
103 bob 99.8
103 tom 77.8
103 德玛 88.8
------------
103 bob 99.8
103 tom 77.8
103 德玛 88.8
101 小法 66.8
100 lucy 88.8
deque容器

deque:双端动态数组
在这里插入图片描述

deque容器和vector容器最大的差异,
一在于deque允许使用常数项时间对头端进行元素的插入和删除操作。
二在于deque没有容量的概念

deque的API

如果迭代器能+1 那么该迭代器为随机访问迭代器

1、deque构造函数;
 deque<T> deqT;//默认构造形式
 deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
 deque(n, elem);//构造函数将n个elem拷贝给本身
 deque(const deque &deq);//拷贝构造函数。
 
2、deque赋值操作
 assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
 assign(n, elem);//将n个elem拷贝赋值给本身。
 deque& operator=(const deque &deq); //重载等号操作符
 swap(deq);// 将deq与本身的元素互换

3、deque大小操作
 deque.size();//返回容器中元素的个数
 deque.empty();//判断容器是否为空
 deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
 deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
 
4、deque双端插入和删除操作
 push_back(elem);//在容器尾部添加一个数据
 push_front(elem);//在容器头部插入一个数据
 pop_back();//删除容器最后一个数据
 pop_front();//删除容器第一个数据

5、deque数据存取
at(idx);//返回索引idx所指的数据,如果idx越界,抛出out_of_range。
operator[];//返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。
front();//返回第一个数据。
back();//返回最后一个数据。

6、deque插入操作
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。

7、deque删除操作
 clear();//移除容器的所有数据
 erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
 erase(pos);//删除pos位置的数据,返回下一个数据的位置
 
stack容器

stack是一种先进后出(First In Last Out,FILO)的数据结构
操作数据的一端 叫栈顶。
top永远指向栈顶元素。
栈容器没有迭代器。不支持遍历行为。

1、stack构造函数
 stack<T> stkT;//stack采用模板类实现, stack对象的默认构造形式:
 stack(const stack &stk);//拷贝构造函数
2、stack赋值操作
 stack& operator=(const stack &stk);//重载等号操作符
3、stack数据存取操作
 push(elem);//向栈顶添加元素
 pop();//从栈顶移除第一个元素
 top();//返回栈顶元素
4、stack大小操作
 empty();//判断堆栈是否为空
 size();//返回堆栈的大小
queue容器

Queue是一种先进先出(First In First Out,FIFO)的数据结构
出数据的一方叫队头,入数据的一方叫队尾。
queue容器没有迭代器 不支持遍历行为。

1、queue的构造函数
queue<T> queT;//queue采用模板类实现,queue对象的默认构造形式:
queue(const queue &que);//拷贝构造函数
2、queue存取、插入和删除操作
push(elem);//往队尾添加元素
pop();//从队头移除第一个元素
back();//返回最后一个元素
front();//返回第一个元素
3、 queue赋值操作
queue& operator=(const queue &que);//重载等号操作符
4、queue大小操作
empty();//判断队列是否为空
size();//返回队列的大小
list容器

list是双向循环链表
list容器的迭代器是 双向迭代器。

1、list构造函数
list<T> lstT;//list采用采用模板类实现,对象的默认构造形式:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将n个elem拷贝给本身。
list(const list &lst);//拷贝构造函数。
2、list数据元素插入和删除操作
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。

remove(elem);//删除容器中所有与elem值匹配的元素
3、list大小操作
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。 如果容器变短,则末尾超出容器长度的元素被删除。
4、list赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
list& operator=(const list &lst);//重载等号操作符
swap(lst);//将lst与本身的元素互换。
5、list数据的存取
front();//返回第一个元素。
back();//返回最后一个元素。
6、list反转排序
reverse();//反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素。
sort(); //list排序(因为list支持双向迭代器,所以sort()不支持list,所以list有自带的sort方法)
//    lists.sort(greater<int>());从大到小

 list<int> l1;
 l1.push_back(10);
 l1.push_back(20);
 l1.push_back(30);
 l1.push_front(40);
 l1.push_front(50);
 l1.push_front(60);

 printListInt(l1);//60 50 40 10 20 30
 //list容器 是双向迭代器 不支持+2 支持++
 list<int>::iterator it=l1.begin();
 it++;
 it++;
 l1.insert(it, 3, 100);
 printListInt(l1);//60 50 100 100 100 40 10 20 30
set/multiset容器

set容器只有键值,在插入数据的时候 自动根据键值排序。不允许有相同的键值。不能修改set容器的元素值,会破坏set的数据结构。set容器的迭代器是只读迭代器(const_iterator)

1、set构造函数
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数
2、set赋值操作
set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
3、set大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空
4、set插入和删除操作
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素

1、set容器默认排序

void printIntSet(set<int> &li){
    set<int>::iterator it;
    for(it=li.begin();it!=li.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    set<int> s1;
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(30);
    s1.insert(50);
    printIntSet(s1);//10 20 30 40 50
}

2、通过仿函数更改set容器排序规则

class MyDesc{
public:
    bool operator()(int v1,int v2) const{ //c++17需要添加const修饰
        return v1>v2;
    }
};

//需要重载 void printIntSet
void printIntSet(set<int,MyDesc> &li){
    set<int>::iterator it;
    for(it=li.begin();it!=li.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}



int main(){
    //通过仿函数更改set容器排序规则
    // set<int,排序规则> s;
    set<int,MyDesc> s2;
    s2.insert(10);
    s2.insert(40);
    s2.insert(20);
    s2.insert(30);
    s2.insert(50);
    printIntSet(s2);//10 20 30 40 50
}

3、如果set容器存放自定义数据 必须更改排序规则

#include <iostream>
#include <set>
#include <string>
using namespace std;

class Person{
    friend class MyCompare;
    friend ostream& operator<<(ostream &out,Person p);
private:
    int num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score){
        this->num=num;
        this->name=name;
        this->score=score;
    }

};
//重写输出运算符
ostream& operator<<(ostream &out,Person p){
    out<<p.num<<" "<<p.name<<" "<<p.score<<" ";
    return out;
}

class MyCompare{

public:
    bool operator()(Person p1,Person p2)const{
        return p1.num<p2.num;
    }
};


void printPersonSet(set<Person,MyCompare> s){
    set<Person,MyCompare>::iterator it;
    for(it=s.begin();it!=s.end();it++){
        cout<<(*it)<<" ";
    }
    cout<<endl;
}

int main(){
    set<Person,MyCompare> s3;

    s3.insert(Person(100, "lucy", 88.8f));
    s3.insert(Person(103, "bob", 99.8f));
    s3.insert(Person(103, "tom", 77.8f));
    s3.insert(Person(103, "德玛", 88.8f));
    s3.insert(Person(101, "小法", 66.8f));
    printPersonSet(s3);//100 lucy 88.8  101 小法 66.8  103 bob 99.8


}

1、set的find和count函数

int main(){
    set<int> s1;
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(30);
    s1.insert(50);
    printIntSet(s1);//10 20 30 40 50
    set<int>::const_iterator ret;
    ret=s1.find(50);
    if(ret!=s1.end()){
        cout<<"找到元素"<<*ret<<endl;
    }
    cout<<s1.count(50)<<endl;//count的结果只能是0或1,因为set容器的key不能重复


}

2、set的equal和range函数

lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器,equal_range的返回值是一个pair对组
int main()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(30);
    s1.insert(50);
    set<int>::iterator ret;
    ret=s1.lower_bound(35);//ret>=35
    cout<<"下限为:"<<*ret<<endl;//40
    ret=s1.upper_bound(35);//ret>35
    cout<<"上限为:"<<*ret<<endl;//40


    pair<set<int>::iterator,set<int>::iterator> p;//equal_range的返回值是对组,第一个值存放>=,第二个值存放>
    p=s1.equal_range(50);
    
    if(p.first!=s1.end()){
        cout<<"下限为:"<<*(p.first)<<endl;

    }
    if(p.second!=s1.end()){
        cout<<"上限为:"<<*(p.second)<<endl;
    }
    
    
    

    return 0;
}

multiset容器:键值允许重复,而set容器的键值不允许重复

int main()
{
    set<int> s;
    pair<set<int>::iterator,bool> ret;

    ret=s.insert(10);
    if(ret.second==true){
        cout<<"第一次插入成功"<<endl;
    }
    else{
        cout<<"第一次插入失败"<<endl;
    }
    ret=s.insert(10);
    if(ret.second==true){
        cout<<"第二次插入成功"<<endl;
    }
    else{
        cout<<"第二次插入失败"<<endl;
    }


    return 0;
}
void printAll(multiset<int> &s){
    multiset<int>::iterator it;
    for(it=s.begin();it!=s.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}


int main()
{
    multiset<int> s;
    s.insert(10);
    s.insert(10);
    s.insert(20);
    printAll(s);//10 10 20



    return 0;
}

对组pair

对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值
可以分别用pair的两个公有属性first和second访问

int main()
{
    //1、方式一
    pair<int,string> p1(10086,"移动");
    pair<int,string> p2(10010,"联通");
    cout<<p1.first<<','<<p1.second<<endl;
    //2、方式二(推荐)
    pair<int,string> p4=make_pair(10000,"电信");
        cout<<p4.first<<','<<p4.second<<endl;

    return 0;
}

map容器/multimap容器

每个元素都是 键值-实值 成对存储,自动根据键值排序, 键值不能重复,不能
修改

1、map构造函数
 map<T1, T2> mapTT;//map默认构造函数:
 map(const map &mp);//拷贝构造函数
 
2、map赋值操作
 map& operator=(const map &mp);//重载等号操作符
 swap(mp);//交换两个集合容器

3、map大小操作
 size();//返回容器中元素的数目
 empty();//判断容器是否为空

4、map插入数据元素操作
 map.insert(...); //往容器插入元素,返回pair<iterator,bool>
 map<int, string> mapStu;
 
// 第一种 通过pair的方式插入对象
 mapStu.insert(pair<int, string>(3, "小张"));
// 第二种 通过pair的方式插入对象
 mapStu.inset(make_pair(‐1, "校长"));
// 第三种 通过value_type的方式插入对象
 mapStu.insert(map<int, string>::value_type(1, "小李"));
// 第四种 通过数组的方式插入值
 mapStu[3] = "小刘";
 mapStu[5] = "小王";

5、map删除操作
 clear();//删除所有元素
 erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
 erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
 erase(keyElem);//删除容器中key为keyElem的对组。

6、map查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
 

示例:

#include <iostream>
#include <map>
#include <string>
using namespace std;

class Person{
    friend void printAll(map<int,Person> &m);
    friend int main();
private:
    int num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score){
        this->num=num;
        this->name=name;
        this->score=score;
    }

};


void printAll(map<int,Person> &m){
    map<int,Person>::iterator ret;
    for(ret=m.begin();ret!=m.end();ret++){
        cout<<(*ret).second.num<<" "<<(*ret).second.name<<(*ret).second.score<<endl;
    }

}


int main()
{
    map<int,Person> m;
    //方式1
    m.insert(pair<int,Person>(103,Person(103,"lucy",88.8f)));
    //方式2
    m.insert(make_pair(101,Person(101,"bob",77.7f)));
    //方式3
 m.insert(map<int,Person>::value_type(102,Person(102,"tom",66.6f)));
    //方式4
    m[104] = Person(104,"德玛", 99.9f);
    printAll(m);


    //查找key为103的元素
    map<int,Person>::const_iterator ret;
    ret=m.find(103);
    if(ret!=m.end()){
        cout<<"找到key=103:";
      cout<<(*ret).second.num<<" "<<(*ret).second.name<<(*ret).second.score<<endl;
    }


    return 0;
}

multimap:键值可以重复的map

容器选择

在这里插入图片描述

算法

函数对象

函数对象:重载了函数调用运算符()的类,实例化的对象叫做函数对象
函数对象+() 触发 重载函数调用运算符执行 ==>类似函数调用 (仿函数)

class Print{


public:
    void operator()(char *str){
        cout<<str<<endl;
    }
};

int main()
{
    Print ob;
    ob("hello world");
//等同于
    Print()("hello");
    
}

如果函数对象 有一个参数 叫:一元函数对象
如果函数对象 有二个参数 叫:二元函数对象
如果函数对象 有三个参数 叫:多元函数对象

谓词

返回值为bool类型的普通函数或仿函数都叫谓词。

如果谓词有一个参数 叫:一元谓词
如果谓词有二个参数 叫:二元谓词

1、一元谓词

一元谓词用于查找

#include <iostream>
#include<vector>
#include<algorithm>//find_if
using namespace std;
//普通函数作为一元谓词
bool greaterThan30(int  value){
    return value>30;
}
//仿函数作为一元谓词
class GreaterThan30{
public:
    bool operator()(int value){
        return value>30;
    }

};

#include<algorithm>
int main()
{


    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    vector<int>::iterator ret;
    //找到大于30的
   // ret=find_if(v1.begin(),v1.end(),greaterThan30);//普通函数写函数名即可
   //仿函数要带上()
    ret=find_if(v1.begin(),v1.end(),GreaterThan30());

    if(ret!=v1.end()){
        cout<<"寻找的结果"<<*ret<<endl;
    }
    return 0;
}

2、二元谓词

二元谓词用于排序

#include <iostream>
#include<vector>
#include <algorithm>
using namespace std;


void printAll(vector<int> v){
    vector<int>::iterator it;
    for(it=v.begin();it!=v.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;


}

/**
 * 普通函数
 */
bool myGreaterInt(int v1,int v2){
    return v1>v2;
}

/**
 *
 * 仿函数
 */
class MyGreaterInt{

public:
    bool operator()(int v1,int v2){
        return v1>v2;
    }
};

int main()
{


    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(20);
    v1.push_back(35);
    printAll(v1);
    
    //sort(v1.begin(),v1.end(),myGreaterInt);//普通函数
    sort(v1.begin(),v1.end(),MyGreaterInt());//仿函数

    printAll(v1);
    return 0;
}

内建函数对象

就是系统提供好的函数对象

1、6个算数类函数对象,除了negate是一元运算,其他都是二元运算。
 template<class T> T plus<T>//加法仿函数
 template<class T> T minus<T>//减法仿函数
 template<class T> T multiplies<T>//乘法仿函数
 template<class T> T divides<T>//除法仿函数
 template<class T> T modulus<T>//取模仿函数
 template<class T> T negate<T>//取反仿函数
 
 2、6个关系运算类函数对象,每一种都是二元运算。
 template<class T> bool equal_to<T>//等于
 template<class T> bool not_equal_to<T>//不等于
 template<class T> bool greater<T>//大于
 template<class T> bool greater_equal<T>//大于等于
 template<class T> bool less<T>//小于
 template<class T> bool less_equal<T>//小于等于
 
 3、逻辑运算类运算函数,not为一元运算,其余为二元运算。
 template<class T> bool logical_and<T>//逻辑与
 template<class T> bool logical_or<T>//逻辑或
 template<class T> bool logical_not<T>//逻辑非
int main()
{

    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(20);
    v1.push_back(35);
    printAll(v1);

    sort(v1.begin(),v1.end(),greater<int>());//使用内建函数对象

    printAll(v1);
    return 0;
}

之前的find_if也可以用内建函数对象

#include <iostream>
#include<vector>
#include<algorithm>//find_if
using namespace std;

int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    vector<int>::iterator ret;
    // ret=find_if(v1.begin(),v1.end(),greaterThan30);//普通函数写函数名即可
    // ret=find_if(v1.begin(),v1.end(),GreaterThan30());
    //使用内置
    ret=find_if(v1.begin(),v1.end(),bind2nd(greater<int>(),30));

    if(ret!=v1.end()){
        cout<<"寻找的结果"<<*ret<<endl;
    }
    return 0;
}

适配器

适配器为算法提供接口。

1、仿函数作为适配器

#include <iostream>
#include<vector>
#include<algorithm>//find_if
using namespace std;

//2:公共继承 binary_function参数萃取
class printInt:public binary_function<int,int,void>{
public:
    //3、整个函数加const修饰
    void operator()(int value,int tmp) const{
        cout<<"value="<<value<<" "<<"tmp="<<tmp<<endl;
    }

};

int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    //1、bind2nd或者bind1st, bind2nd将100绑定都第二个参数tmp行 容器的元素在value上
    for_each(v1.begin(),v1.end(),bind2nd(printInt(),100));
    return 0;
}

在这里插入图片描述

2、普通函数作为适配器ptr_fun

/*
普通函数
*/
void myPrintInt(int value,int tmp){
    cout<<"value="<<value<<"tmp="<<tmp<<endl;
}
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    //使用ptr_fun转换
for_each(v1.begin(),v1.end(),bind2nd(ptr_fun(myPrintInt),100));
    return 0;
}

3、成员函数作为适配器 mem_fun_ref

#include <iostream>
#include<vector>
#include<algorithm>//find_if
using namespace std;
class Person{
private:
    int data;
public:

    Person(){}
    Person(int d){
        data=d;
    }
    void printPerson(int tmp){
        cout<<"data="<<data<<" "<<"tmp"<<tmp<<endl;
    }
};



int main()
{
    vector<Person>v1;
    v1.push_back(Person(10));
    v1.push_back(Person(15));
    v1.push_back(Person(30));
    v1.push_back(Person(20));
    v1.push_back(Person(50));
    for_each(v1.begin(),v1.end(),bind2nd(mem_fun_ref(&Person::printPerson),10));
    return 0;
}

打印结果:

data=10 tmp10
data=15 tmp10
data=30 tmp10
data=20 tmp10
data=50 tmp10

4、取反适配器

①not1 一元取反

vector<int>v1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);

vector<int>::iterator ret;
ret=find_if(v1.begin(),v1.end(),not1(bind2nd(greater<int>(),10)));//>10取反<=10
if(ret!=v1.end()){
    cout<<*ret<<endl;//10
}

②not2 二元取反

    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);

    vector<int>::iterator ret;
    sort(v1.begin(),v1.end(),not2(greater<int>()));//从大到小排序取反  从小到大
    vector<int>::iterator it;
    for(it=v1.begin();it!=v1.end();it++){
        cout<<*it<<endl;
    }
lambda表达式
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
//lambda表达式c++11才支持
//[]里面啥都不写 lambda不能识别外部数据
//[=]lambda能对外部数据 读操作
//[&]lambda能对外部数据 读写操作
    for_each(v1.begin(),v1.end(),[](int val){
        cout<<val<<endl;
    });
    int a=10;
    for_each(v1.begin(),v1.end(),[=](int val){
        cout<<val<<"a="<<a<<endl;//能够读取外部数据a
    });

    for_each(v1.begin(),v1.end(),[&](int val){
        a=100;//能够修改外部数据a
    });
    cout<<"a="<<a<<endl;//a=100

常见遍历算法

1、for_each遍历算法

/*
遍历算法 遍历容器元素
@param beg 开始迭代器
 @param end 结束迭代器
 @param _callback 函数回调或者函数对象
@return 函数对象
*/
for_each(iterator beg, iterator end, _callback);

2、transform算法

transform算法 将指定容器区间元素搬运到另一容器中

 
 @param beg1 源容器开始迭代器
 @param end1 源容器结束迭代器
 @param beg2 目标容器开始迭代器
 @param _cakkback 回调函数或者函数对象
 @return 返回目标容器迭代器
 */
 transform(iterator beg1, iterator end1, iterator beg2, _callbakc);

实例:

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;

void printAll(vector<int> v){
    vector<int>::iterator it;
    for(it=v.begin();it!=v.end();it++){
        cout<<*it;
    }
    cout<<endl;
}
//将传递过来的数据直接返回,不做任何操作
int myTransInt(int val){
    return val;//val是遍历v的数据
}

int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);

    vector<int>v2;
    //注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
    v2.resize(v.size());
    transform(v.begin(),v.end(),v2.begin(),myTransInt);
    printAll(v2);
    return 0;
}

常见查找算法

1、find算法 查找元素

/*
 find算法 查找元素
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param value 查找的元素
 @return 返回查找元素的位置
 */
 find(iterator beg, iterator end, value)

①查找基本类型数据

int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    vector<int>::iterator ret;

    ret=find(v.begin(),v.end(),30);
    if(ret!=v.end()){
        cout<<"查找到元素"<<*ret<<endl;
    }
    return 0;
}

②查找自定义数据类型

查找自定义数据类型 需要重载==

class Person{
    friend int main();
private:
    int num;
    string name;
public:
    Person(){}
    Person(int num,string name){
        this->num=num;
        this->name=name;
    }
    bool operator==(const Person &ob){
        return (this->num==ob.num)&&(this->name==ob.name);
    }
};
int main()
{
    vector<Person> v2;
    v2.push_back(Person(10,"bob"));
    v2.push_back(Person(20,"tom"));
    v2.push_back(Person(30,"lucy"));

    vector<Person>::iterator ret;
    ret=find(v2.begin(),v2.end(),Person(10,"bob"));
    if(ret!=v2.end()){
        cout<<"查找到元素"<<(*ret).num<<(*ret).name<<endl;
    }
    return 0;
}

2、find_if算法 条件查找

int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);

    // vector<Person> v2;
    // v2.push_back(Person(10,"bob"));
    // v2.push_back(Person(20,"tom"));
    // v2.push_back(Person(30,"lucy"));

    vector<int>::iterator ret;
    ret=find_if(v.begin(),v.end(),bind2nd(greater<int>(),20));
    if(ret!=v.end()){
        cout<<"查找到元素"<<(*ret)<<endl;
    }
    return 0;
}

3、adjacent_find算法 查找相邻重复元素

 /*
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param _callback 回调函数或者谓词(返回bool类型的函数对象)
 @return 返回相邻元素的第一个位置的迭代器
 */
 adjacent_find(iterator beg, iterator end, _callback);
int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(30);


    vector<int>::iterator ret;
    ret=adjacent_find(v.begin(),v.end());
    if(ret!=v.end()){
        cout<<"查找到第一个相邻重复元素"<<(*ret)<<endl;//30
    }
    return 0;
}

4、binary_search算法 二分查找法

注意: 在无序序列中不可用

int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(30);
    v.push_back(15);

    vector<int>::iterator ret;
    sort(v.begin(),v.end());
    //注意返回值是bool类型
    bool result=binary_search(v.begin(),v.end(),30);
    if(result){
        cout<<"查找到元素"<<endl;
    }
    else{
        cout<<"没找到元素"<<endl;
    }
    return 0;
}

5、count算法 统计元素出现次数

 /*
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param value
 @return int返回元素个数
 */
 count(iterator beg, iterator end, value);
int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(30);
    v.push_back(15);


    vector<int>::iterator ret;
    int c=count(v.begin(),v.end(),30);
    cout<<c<<endl;//2
    return 0;
}

6、count_if算法 统计元素出现次数

int main()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(30);
    v.push_back(15);


    vector<int>::iterator ret;
    //统计大于10的元素个数a
    int c=count_if(v.begin(),v.end(),bind2nd(greater<int>(),10));//4
    cout<<c<<endl;
    return 0;
}

常见排序算法

1、merge算法 容器元素合并

 /*
 merge算法 容器元素合并,并存储到另一容器中
 注意:两个容器必须是有序的
 @param beg1 容器1开始迭代器
 @param end1 容器1结束迭代器
 @param beg2 容器2开始迭代器
 @param end2 容器2结束迭代器
 @param dest 目标容器开始迭代器
 */
 merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
void printAll(vector<int> v){
    vector<int>::iterator it;
    for(it=v.begin();it!=v.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);

    vector<int>v2;
    v2.push_back(20);
    v2.push_back(40);
    v2.push_back(60);
    v2.push_back(80);

    vector<int>v;
    v.resize(v1.size()+v2.size());
    merge(v1.begin(),v1.end(),v2.begin(),v2.end(),v.begin());
    printAll(v);
    return 0;
}

打印输出

10 20 30 40 50 60 70 80

2、sort算法 容器元素排序

 /*
 sort算法 容器元素排序
 @param beg 容器1开始迭代器
 @param end 容器1结束迭代器
 @param _callback 回调函数或者谓词(返回bool类型的函数对象)
 */
 sort(iterator beg, iterator end, _callback)

3、random_shuffle算法 对指定范围内的元素随机调整次序

int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);
    srand(time(NULL));//添加随机种子
    random_shuffle(v1.begin(),v1.end());

    printAll(v1);
    return 0;
}

4、reverse算法 反转指定范围的元素

 /*
 reverse算法 反转指定范围的元素
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 */
 reverse(iterator beg, iterator end)

常见拷贝替换算法

1、copy算法

 /*
 copy算法 将容器内指定范围的元素拷贝到另一容器中
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param dest 目标起始迭代器
 */
copy(iterator beg, iterator end, iterator dest)
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);

    vector<int>v2;
    v2.resize(v1.size());
    copy(v1.begin(),v1.end(),v2.begin());
    printAll(v2);
    return 0;
}

copy的进阶用法:

遍历vector容器打印元素

#include <iostream>
#include<vector>
#include<algorithm>
#include<iterator>
using namespace std;
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);

//#include<iterator>
    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

2、replace算法

/*
 replace算法 将容器内指定范围的旧元素修改为新元素
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param oldvalue 旧元素
 @param oldvalue 新元素
 */
replace(iterator beg, iterator end, oldvalue, newvalue)
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);


    replace(v1.begin(),v1.end(),30,3000);//将30替换成3000
    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

输出结果:

10 3000 50 70

3、 replace_if算法

 /*
 replace_if算法 将容器内指定范围满足条件的元素替换为新元素
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param callback函数回调或者谓词(返回Bool类型的函数对象)
 @param oldvalue 新元素
 */
 replace_if(iterator beg, iterator end, _callback, newvalue)
class GreaterThan30{
public:
    bool operator()(int val){
        return val>30;
    }
};
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);


    replace_if(v1.begin(),v1.end(),GreaterThan30(),3000);//将>30替换成3000
    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

4、swap算法

 /*
 swap算法 互换两个容器的元素
 @param c1容器1
 @param c2容器2
 */
 swap(container c1, container c2)

常用算数生成算法

1、accumulate算法 计算容器元素累计总和

需要引入头文件#include<numeric>

/*
2 accumulate算法 计算容器元素累计总和
3 @param beg 容器开始迭代器
4 @param end 容器结束迭代器
5 @param value累加值 (注意:求和完后 + value)
6 */
7 accumulate(iterator beg, iterator end, value)
#include <iostream>
#include<vector>
#include<algorithm>
#include <string>
#include<iterator>
#include<numeric>
using namespace std;
int main()
{
    vector<int>v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);
    v1.push_back(70);

    //#include<numeric>
   int all=accumulate(v1.begin(),v1.end(),0);
    cout<<all<<endl;
    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

2、fill算法 向容器中添加元素

/*
 fill算法 向容器中添加元素
 @param beg 容器开始迭代器
 @param end 容器结束迭代器
 @param value t填充元素
 */
 fill(iterator beg, iterator end, value)
int main()
{
    vector<int>v1;
    v1.resize(5);

    fill(v1.begin(),v1.end(),5);

    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

输出结果:

5 5 5 5 5

如果v1中有元素

int main()
{
    vector<int>v1;
    v1.resize(5);
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(50);

    fill(v1.begin(),v1.end(),5);

    copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

打印结果:

5 5 5 5 5 5 5 5

常用集合算法

在这里插入图片描述

1、set_intersection求两个set集合的交集

 /*
 set_intersection算法 求两个set集合的交集
 注意:两个集合必须是有序序列
 @param beg1 容器1开始迭代器
 @param end1 容器1结束迭代器
 @param beg2 容器2开始迭代器
 @param end2 容器2结束迭代器
 @param dest 目标容器开始迭代器
 @return 目标容器的最后一个元素的迭代器地址
 */
 set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2,iterator dest)
int main()
{
     vector<int> v1;
     v1.push_back(1);
     v1.push_back(3);
     v1.push_back(5);
     v1.push_back(7);
     v1.push_back(9);

     vector<int> v2;
     v2.push_back(7);
     v2.push_back(9);
     v2.push_back(11);
     v2.push_back(13);
     v2.push_back(15);

      vector<int> v3;//存放交集
      v3.resize( min(v1.size(), v2.size()));

      vector<int>::iterator ret;
      // return目标容器的最后一个元素的迭代器地址
      ret = set_intersection(v1.begin(), v1.end(), v2.begin(),v2.end(), v3.begin());

      copy(v3.begin(), ret, ostream_iterator<int>(cout, " ") );
      cout<<endl;

    return 0;
}

输出结果

7 9

2、 set_union算法 求两个set集合的并集

/*
 set_union算法 求两个set集合的并集
 注意:两个集合必须是有序序列
 @param beg1 容器1开始迭代器
 @param end1 容器1结束迭代器
 @param beg2 容器2开始迭代器
 @param end2 容器2结束迭代器
 @param dest 目标容器开始迭代器
 @return 目标容器的最后一个元素的迭代器地址
 */
 set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
int main()
{
     vector<int> v1;
     v1.push_back(1);
     v1.push_back(3);
     v1.push_back(5);
     v1.push_back(7);
     v1.push_back(9);

     vector<int> v2;
     v2.push_back(7);
     v2.push_back(9);
     v2.push_back(11);
     v2.push_back(13);
     v2.push_back(15);



      vector<int> v3;//存放交集
      v3.resize( v1.size()+v2.size());

     vector<int>::iterator ret;
      ret = set_union(v1.begin(), v1.end(), v2.begin(),v2.end(), v3.begin());

      copy(v3.begin(), ret, ostream_iterator<int>(cout, " ") );
      cout<<endl;




    // copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

输出结果:

1 3 5 7 9 11 13 15

3、set_difference算法 求两个set集合的差集

/*
 set_difference算法 求两个set集合的差集
 注意:两个集合必须是有序序列
 @param beg1 容器1开始迭代器
 @param end1 容器1结束迭代器
 @param beg2 容器2开始迭代器
 @param end2 容器2结束迭代器
 @param dest 目标容器开始迭代器
 @return 目标容器的最后一个元素的迭代器地址
 */
 set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
int main()
{
     vector<int> v1;
     v1.push_back(1);
     v1.push_back(3);
     v1.push_back(5);
     v1.push_back(7);
     v1.push_back(9);

     vector<int> v2;
     v2.push_back(7);
     v2.push_back(9);
     v2.push_back(11);
     v2.push_back(13);
     v2.push_back(15);



      vector<int> v3;//存放交集
      v3.resize(v1.size());//求A差B size就设置成A ,求B差A size结果就设置成B

     vector<int>::iterator ret;
      ret = set_difference(v1.begin(), v1.end(), v2.begin(),v2.end(), v3.begin());

      copy(v3.begin(), ret, ostream_iterator<int>(cout, " ") );
      cout<<endl;




    // copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值