ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STL 标准模板库

2021-11-11 12:34:58  阅读:122  来源: 互联网

标签:容器 begin end string iterator STL 标准 int 模板


STL意义:在数据结构和算法方面建立一套标准,提高代码复用性。

STL广义分类:容器 算法 迭代器

                        容器和算法通过迭代器进行无缝连接

STL几乎所有代码都采用模板类或模板函数

STL六大组件:

容器:将各种常用的数据结构实现出来,用来存放数据 vector\list\deque\set\map...

           常用数据结构:数组、链表、树、栈、队列、集合、映射表...

           序列式容器:强调值的排序,每个元素均有固定的位置

           关联式容器:二叉树结构,各元素之间没有严格的顺序关系

算法 Algorithms

            质变算法:运算过程中会更改区间内元素的内容 eg 拷贝、删除

            非质变算法:运算过程中不会更改区间内元素的内容 eg 查找、计数

迭代器:容器与算法之间的胶合剂。提供一种方法,其能够依序访问某容器所含各个元素,同时                   无需暴露容器内部表示方式。

             1. 算法要通过迭代器才可以访问容器中元素

             2.每个容器都有自己专属的迭代器

             3.迭代器行为类似指针,初学时可暂理解为指针

仿函数:重载() 协助算法

适配器:修饰容器、仿函数、迭代器的接口

空间配置器:空间配置和管理

STL初识:

vector存放内置、自定义数据类型

1.vector存放内置数据类型

   #include <vector>


    //创建vector容器,可看做(整型)数组
    vector<int> v;

    //用尾插法写入两个数据
    v.push_back(10);
    v.push_back(20);

方法1: 

    vector<int>::iterator itBegin = v.begin(); //起始迭代器 指向容器中第一个元素
    vector<int>::iterator itEnd = v.end();   //结束迭代器 指向容器中最后一个元素的下一个位置
    while (itBegin != itEnd)
    {
        cout << *itBegin << endl;
        itBegin++;
    }

方法2:将法1做简化

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

方法3:利用vector内置的遍历算法 ,需要利用函数回调,即myPrint函数在for_each中使用时调用 

#include<algorithm>   //算法头文件

void myPrint(int val)   //传入容器的数据是int,因此此处也形参也为int

{

      cout<<val<<endl;


for_each(v.begin(), v.end(), myPrint); 

 2.vector存放自定义数据类型

vector<Person> v;  类似

容器嵌套容器

——类比二维数组

大容器中储存小容器,小容器中储存int类型数据

for (vector<vector<int>> ::iterator it = v.begin(); it != v.end(); it++)
    {                                       //*it 的类型是<>内的内容,即小vector容器.因此需要在内层遍历.
        for (vector<int> ::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
        {                //int类型
            cout << *vit << " ";
        }
        cout << endl;
    }

String容器

本质:string是一个类。类内部封装char* 管理这个字符串 是一个char*型容器 

1.string的构造函数

   函数原型                                           意义、使用

string()                                            创建空字符串 string s1; 

string(const char* s)                       使用字符串s初始化(c风格)

                                                       const char* str = "hello world"

                                                       string s2(str);

string (const string & str)                 拷贝构造 string s3(s2) 

string(int n , char c)                         使用n个字符c初始化 string s4(10, ‘ a ') 

2.string的赋值操作 

operator= 赋值 更为常用。

函数原型

string& operator=(const char* s)                                  string s1 = "hello world"

string& operator=(const string & s)                              string s2 = s1 ;

string& operator=(char c)                                             string s3 = 'a' ;


string& assign(const char* s)                                        s4.assign("hello world")

string& assign(const char* s , int n)                              s5.assign(s4 , 5)    //把s前n个字符赋给当前                                                                                                                                                  字符串

string& assign(const string & s)                                    s6.assign(s5)         //拷贝构造

string& assign(int n , char c)                                         s7.assign(5, 'a')     //输出5个a

3.string字符串拼接 

法一 :operator+=   重载      

                                                                                string str1 = "我";

string& operator+= (const char * s)                         str1+= "爱玩游戏"        //追加多个字符

string& operator+= (const char c)                           str1 +=  ' : '                  //追加单个字符 

string& operator+= (const string & s)                      str2 = "LOL" ; str1 += str2; //连接另一个字符串   


法二:append函数

                                                                             str3 = " I "

string& append(const char* s)                             str3.append(" love ")

string& append(const char* s , int n)                   str3.append("Game abc" , 4) 

                                                                            //拼接s中前4个字符  (Game)

string& append(const string &s)                          str3.append(str2)  //s2接在str3末尾

string& append(const string &s , int pos,int n)     str3.append(str2,0,3)   

                                                                            //str2从0号位置开始接入,一共接入3个字符

4.string查找和替换 

查找:find函数/ rfind函数

int pos = s1.find(" 字符串 ")

若找到,返回第一个字符的位置; 若未找到,返回 -1 

    string s1 = "abcde";
	int pos = s1.find("de");
	if (pos == -1)
	{
		cout << "未找到该字符串" << endl;
	}
	else
	{
		cout << "该字符串于" << pos << "位置找到" << endl;
	}

 rfind:从右往左查,查到的第一个字符串的位置,返回。

替换:replace函数

s1.replace( 1 , 3 , "1111")

//从1号位置起 3个字符 替换为"1111" 

5.string字符串比较 compare函数

利用字符的ASCII码值比较

int a = s1.compare(s2);

s1 = s2               ----------------------- a = 0

s1 > s2               ----------------------- a = 1

s1 < s2               ----------------------- a = -1

 6.string字符存取         [] 或 at =函数

读:           读取单个字符

    string s1 = "abcde";
    for (int i = 0; i < s1.size(); i++)
    {
        cout << s1[i] << " ";
        cout << endl;
    }
    for (int i = 0; i < s1.size(); i++)
    {
        cout << s1.at(i) << " ";
        cout << endl;
    }

写:              修改单个字符

    s1[0] = 'x';
    s1.at(1) = 'x'; 

7.string插入和删除 

插入 insert函数

删除 erase函数

string s1 = "abcde";
    s1.insert(1,"111");              //从1号位置开始 , 插入“111”
    //a111bcde
    cout << s1; 
    s1.erase(1, 3);                   //从1号位置开始,删除3个字符
    //abcde
    cout << s1;

8.string子串 

    string s1 = "abcde";
    string subStr = s1.substr(1,3);         //从1号位置开始,截取3个字符
    //bcd
    cout << subStr;

实用操作:获取有效信息

//从邮箱截取姓名

void getName()
{
    string str1 = " zhangsan@163.com";
    int pos = str1.find("@");
    string usrName = str1.substr(0, pos);
    cout << "姓名为" << usrName;

Vector容器 

1.基本概念:

和数组非常相似,也称为单端数组(在数组尾端添加/删除)

与数组区别:数组是静态空间,不能扩容,而vector可以动态扩展

                      动态扩展:找到更大的内存空间,将原数据拷贝到新空间,然后释放原空间。

 2.vector构造函数

创建vector容器,可以赋初值

//无参构造    

    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }


//将区间[ v1.begin() , v1.end() ) 传入v2
    vector<int> v2(v1.begin() , v1.end());


//传入10个100
    vector<int> v3(10,100);


//拷贝构造
    vector<int> v4(v3);

3.vector赋值操作 

等号赋值

  vector<int>v1 = v0;


assign赋值

    //区间 [ v0.begin(), v0.end() ) 赋值
    vector<int>v2;
    v2.assign(v0.begin(), v0.end());

    //n个 element 赋值
    vector<int>v3;
    v3.assign(10, 100);

4.vector容量和大小

empty()     判断容器是否为空   返回true/false

capacity()  容器容量  返回int

size()         返回容器中元素的个数(<= 容量)

resize()

resize()

//重新指定容器大小

v1.resize( 10 )           //如果重新指定的比原来要长,默认用0填充新的位置,此时vector发生                                    动态扩展,新的容量会比10更大一点

v1.resize( 10,100)                       // 利用参数2可以指定填充新位置的数字,从0变为100

v1.resize( 1 )            //如果重新指定的比原来要短,多余的会被删除,size变小,容量不变

5.vector插入和删除

push_back(ele)                                                         尾插元素ele

insert(const_interator pos , ele)                                迭代器指向位置pos插入元素ele

insert(const_interator pos ,int count  ,  ele)              迭代器指向位置pos插入count个元素ele


pop_back(ele)                                                           尾删元素ele

erase(const_interator pos)                                        删除迭代器指向位置的元素

erase(const_interator start ,  const_interator end)    删除迭代器从start到end之间的元素

clear()                                                                        删除容器中所有元素

6.vector数据存取

v0[1]          返回第1号元素
v0.at(1)      返回第1号元素

v0.front()   返回容器第一个元素(第0号)

v0.back()   返回容器最后一个元素

7.vector互换容器

实现两个容器互换        swap函数

v2.swap(v1)

实际用途:收缩内存空间

当我们resize容器后,size会变小但capacity不会,造成内存的浪费。

创建匿名对象x ,将v1拷贝到x上,此时的v1.size()为2,因此x只会开辟很小的容量。

swap后,v1的容量变为小容量,而匿名对象x在本行代码执行结束后销毁。

vector<int> v1;
    for (int i = 0; i < 10000; i++)
    {
        v1.push_back(i);
    }
    cout << "v1容量为" << v1.capacity() << endl;  //12138
    cout << "v1大小为" << v1.size() << endl;        //10000
    v1.resize(2);

    //匿名对象
    vector<int>(v1).swap(v1);  
    cout << "v1容量为" << v1.capacity() << endl;  //2
    cout << "v1大小为" << v1.size() << endl;        //2

8.vector预留空间

reserve(int len)

当插入数据比较大时,vector会随着数据插入不断做动态扩展。利用reserve可以提前预留空间,减少动态扩展次数。

vector<int> v1;
    int* p = NULL;
    int num = 0;
    for (int i = 0; i < 10000; i++)
    {
        v1.push_back(i);
        if (p != &v1[0])            //利用动态扩展会找一块新的内存空间的特性,统计动态扩展次数
        {
            p = &v1[0];
                num++;
        }
    }
    cout << num;                // 24

提前预留空间后,动态扩展只有初始的1次.

v1.reserve(10000);

cout<<num;             // 1  


Deque容器 

双端数组,可以对头端进行插入删除操作

Deque与Vector: 

                         1.Deque对于头部插入删除的效率高、速度快;

                         2.Deque访问元素时速度比Vector慢,与二者内部实现有关。Deque容器由中控器                              和缓冲区组成,中控器记录不同缓冲区的地址,当现有缓冲区被数据占满时,中                              控器指向新的地址,开辟缓冲区,继续储存数据。

1.deque构造函数

deque<int> d1;

deque<int>d2(d1.begin(),d1.end());

deque<int>d3(10,100);

deque<int>d4(d3);

2.deque赋值

d2 = d1;

d3.assign(d1.begin(),d1.end());

d4.assign(10,100);

3.deque大小操作

d1.empty()

d1.size()

d1.resize(num)             //若容器变短辟,默认0填充新位置

d1.resize(num, elem)   //若容器变长,以elem填充新位置

//deque没有容量的概念

4.deque插入和删除

两端操作:

push_back(num)  //尾插

push_front(num)  //头插

pop_back()          //尾删

pop_front()          //头删

指定位置操作:

//用insert要提供迭代器

insert(pos , elem)        //在pos位置插入一个elem元素的拷贝,返回新数据的位置

insert(pos , n , elem)   // 在pos位置插入n个elem元素的拷贝,无返回值

insert(pos , beg , end) // 在pos位置插入区间[beg , end )的数据,无返回值

clear() //清空

erase(beg,end)           //删除区间数据,返回下一个数据的位置

erase(pos)                  //删除位置上数据,返回下一个数据的位置

5.deque数据存取

d1[int ]        //访问第i个元素

d1.at( int )

front()  //返回第一个元素

back()

6.deque排序操作

#include<algorithm>

sort(d.begin(),d.end())

默认排序规则:从小到大升序排列

对于支持随机访问的迭代器的容器,都可以用sort算法直接进行排序(如vector)

stack容器

特点:只有一个出口,先进的后出。

          栈底密封,栈顶开口,从栈顶进出。

          不允许有遍历行为,因为除栈顶处之外的元素外界 访问不到。

类比:挤地铁、弹匣

入栈 push              出栈 pop

stack的常用接口:

push(elem)  入栈

pop()            栈顶元素出栈

empty()        是否为空

size()            栈的大小

queue容器

入队 push

出队 pop

返回队头元素 front

返回队尾元素 back

判断是否为空 empty

返回队列大小 size

list容器   链表

链表由一系列结点组成,而结点由数据域和指针域组成。

数据域储存本结点处元素,指针域储存下一个结点数据的地址。

通过指针实现元素之间的逻辑顺序

 list的优点:

                    动态存储分配,不会造成内存浪费和溢出。(用多少开多少)

                    执行插入和删除操作很方便,修改指针即可,不需移动大量元素。

list的缺点: 需要的内存空间大,遍历所需的时间长。

list和vector是两个重要的容器,他们的优缺点是互补的。

1.list构造函数

    list<int>l1;
    l1.push_back(10);
    l1.push_back(20);



    list<int>l2(l1.begin(), l1.end());


//拷贝构造
    list<int>l3(l2);


//10个1000 


    list<int>l4(10, 1000);

2.list赋值和交换 

//operator=

L2 = L1;

//assign

L2.assign(L1.begin(),L1.end());

L3.assign(10,100);  //赋值:10个100

swap

L1.swap(L2); 

3.list大小操作

//和vector相同

size()

empty()

resize(num)

resize(num,elem) 

4.list插入和删除

与之前相同:

push_back(num)  //尾插

push_front(num)  //头插

pop_back()          //尾删

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)           //删除区间数据,返回下一个数据的位置

erase(pos)                  //删除位置上数据,返回下一个数据的位置

新增:

remove(elem)      //删除容器中所有与elem值匹配的元素 

5.list数据存取 

与vector不同!

( [ ] 、 at 不行 , 因为list是链表,不用连续线性空间储存数据,迭代器也不支持随机访问。)

访问第一个元素  front()

访问最后一个元素 back()

技巧:判断容器迭代器的性质

list<int>::iterator it = L1.begin(); //创建迭代器

//支持双向

it++;

it--;


//不报错-->支持随机访问;报错则不支持。(能否跳跃式访问数据)

it = it + 1; it = it + 2...

6.list反转和排序

L.reverse();         //1 2 3 4 5 ----> 5 4 3 2 1 

//所有不支持随机访问迭代器的容器,不可以用标准算法

//他们的内部会提供对应的一些算法(成员函数)

//sort(L1.begin(),L1.end())        错误

L1.sort();              //默认从小到大,升序

//改变排序方式为降序:

bool mycompare(int v2,int v2)

{

 return v1 > v2;

}

L1.sort(mycompare)

set/multiset 容器

所有元素会在插入时自动被排序

本质:属于关联式容器,底层用二叉树实现

二者区别:set不允许容器中有重复元素,而multiset允许。

1.set容器构造和赋值

set<int> s1;

set<int>s2(s1);

赋值:

s3 = s2;

2.set大小和交换 

set不提供resize

empty();

size();

s2.swap(s1);

3.set插入和删除

插入只有insert一种 

插入时会自动排序,默认升序

插入的重复值会被自动忽略

set<int>s1; 

s1.insert(10);

s1.insert(5);

s1.insert(100);

s1.insert(5);          //无效 

erase(pos)                     //删除pos位置迭代器对应的元素

erase(elem)                   //删除元素elem

clear(); erase(s.begin(),s.end())      //清空 

4.set查找和统计

查找:

set<int>::iterator pos = s1.find(30)      //查找set中有没有30,返回的是迭代器

if(pos != s1.end())                                //找到了元素,值为*pos = 30 

else                                                      //未找到

 统计:

int num = s1.count(30)                //返回容器中30的个数

                                                   //对于set容器,值为0或1.(无重复元素)

5.pair 对组的创建

利用对组可以返回两个数据

不用包含头文件

//创建法1

pair<type1,type2> p ( 数据1,数据2)

//创建法2

pair<type1,type2> p2 = make_pair(数据1,数据2) 

//访问   

p.first ;     p.second

6.set容器排序(内置类型)

set容器默认排序规则为从小到大,利用仿函数可以改变排序规则。 

class MyCompare
{
public:
	bool operator()(int v1,int v2)
	{
		return v1 > v2;
	}
};
void test01()
{
	set<int,MyCompare>s1;
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	for (set<int, MyCompare>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

7.set容器排序(自定义数据类型)

自定义数据类型放到set容器中,必须利用仿函数指定排序规则,否则编译器不知道怎么处理。

class Person
{
public:
	Person(string name, int age)
	{
		m_Name = name;
		m_Age = age;
	}
	string m_Name;
	int m_Age;
};
class ComparePerson
{
	bool operator()(const Person &p1,const Person &p2)
	{
		//按年龄降序
		return p1.m_Age > p2.m_Age;
	}
};
void test01()
{
	set<Person, ComparePerson>s1;
	Person p1("张三", 18);
	Person p1("李四", 100);
	Person p1("王五", 90);
	for (set<Person, ComparePerson>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << (*it).m_Age << " " << (*it).m_Name << endl;
	}
}

map/multimap容器(重要)

简介:

map中所有元素都是pair(对组)

pair中第一个元素为key,索引作用;第二个元素为value,实值

所有的元素会按 键值key自动排序(升序)

本质:属于关联式容器,底层结构由二叉树实现

优点:能根据key值快速找到value值

map与multimap:map不允许容器中有重复的key值元素

                            multimap允许容器中有重复key值元素

                            二者都允许重复的value值

1.map构造和赋值

默认构造

插入数据时要插入对组pair,因为map容器中存放的元素是对组

    map<int, int>m1;
	m1.insert(pair<int,int>(1, 10));
	m1.insert(pair<int, int>(3, 30));
	m1.insert(pair<int, int>(2, 20));
	for (map<int, int>::iterator it = m1.begin(); it != m1.end(); it++)
	{
		cout << (*it).first << " " << it->second << endl;
	}

拷贝构造

map<int,int>m2(m1);

赋值

map<int,int>m3;

m3 = m2;

 2.map大小和交换

size();

empty();

swap(m);

3.map插入和删除

插入

m.insert(pair<int,int>(1,10));

m.insert(make_pair(2,20));

m[3] = 30;                           //不建议插数时使用,推荐在访问已有键值对时使用

删除

erase(pos)                 //pos是迭代器

erase(key);                //按照key删除! 

erase(beg,end)         // 等价于clear()

4.map查找和统计 

find(key)                         //若找到,返回key所在位置迭代器;若未找到,返回end()

map<int, int>::iterator pos = m1.find(3);
if(pos != m.end())            //找到了,key为(*pos).first; value为pos->second
else                          //没找到

count(key)                      //统计指定key的个数 ,返回整数

                                      // map,0或1; multimap可能大于1

5.map排序 

默认排序是按key值从小到大,利用仿函数改变排序规则

class MyCompare
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
void test01()
{
	map<int, int,MyCompare>m1;
	m1.insert(make_pair(1, 10));
	m1.insert(make_pair(2, 20));
	for (map<int, int,MyCompare>::iterator it = m1.begin(); it != m1.end(); it++)
	{
		cout << (*it).first << " " << it->second << endl;
	}
	
}

案例tips

1. 前面创建好迭代器it,后面for循环使用it时,第一个参数不用填写。

2.可以用count和index来遍历部分容器,减少运算。

    multimap<int,Worker>::iterator it = m.find(0);
    int index = 0;
	int count = m.count(0);
	for (; it != m.end() && index < count; it++, index++)
	{
		cout << it->second.m_Name << " " << it->second.m_Salary << endl;
	}

3.用下面这种向函数传入两个容器的方式,可以在遍历A容器的同时给B容器传值(*it)

void setWorker(vector<Worker> &v, multimap<int, Worker>& m)
{
	for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
	{
		int deptNum = rand() % 3;
		//将员工插入分组
		m.insert(make_pair(deptNum, *it));
	}
}



函数对象(仿函数)

1.函数对象使用时,可以像普通函数一样调用。可以有参数和返回值。

class MyAdd
{
public:
	int operator()(int v1, int v2)
	{
		return v1 + v2;
	}
};
void test01()
{
	MyAdd ad;
	cout<<ad(10, 20);
}

2.函数对象可以有属于自己的状态

仿函数写在类中,因此可以通过创建类内的变量来描述函数对象的状态。下面例子中,用count记录函数对象调用的次数。

class MyPrint
{
public:
	MyPrint()
	{
		count = 0;
	}
	void operator()(string text)
	{
		cout << text << endl;
		count++;
	}
	int count;
};
void test01()
{
	MyPrint mp;
	mp("Hello World");
	mp("Hello World");
	mp("Hello World");
	cout << mp.count << endl;
}

3.函数对象可以作为参数传递

class MyPrint
{
public:
	void operator()(string text)
	{
		cout << text << endl;
	}
};
void doPrint(MyPrint& mp, string text)
{
	mp(text);
}

谓词

概念:返回bool类型的仿函数

若operator() 接收一个参数,称为一元谓词;接收两个参数,称为二元谓词。

一元谓词:

class GreaterThanFive
{
public:
	bool operator()(int a)
	{
		return a > 5;
	}
};
void test01()
{
	vector<int>v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	                                                       //匿名对象
	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterThanFive());
	if (it != v.end())
	{
		cout << "找到了,值为" << *it;
	}
	else
		cout << "未找到" << endl;
}

内建函数对象

C++内部别人写好的仿函数,可以直接用。

包含头文件:#include<functional>

1.算数仿函数

negate  取反仿函数

negate<int>p;

p(50);                //-50

plus 加法仿函数

plus<int>p;       //二元的也只需传入一个int,因为默认相加二者类型相同

p(10,20);          //30 

minus 减法

multiples 乘法

divides 除法

modulus 取模 

2.关系仿函数 

上文实现了改变sort函数排序规则:

class MyCompare
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
sort(v.begin(),v.end(),MyCompare())

而利用内置关系仿函数greater,可以快速实现,不用自己写仿函数。

sort(v.begin(),v.end(),greater<int>())

其他关系仿函数:(不常用)

bool equal_to<T>           //等于                                           equal_to<int>()

bool not_equal_to<T>

bool greater_equal<T> //大于等于

bool less<T>

bool less_equal<T>

3.逻辑仿函数(开发中几乎用不到)

bool logical_and<T> ()      //与

bool logical_or<T> ()         //或

bool logical_not<T>  ()      //非



STL常用算法

1.遍历

for_each

for_each(v.begin(),v.end(),print01)              //普通函数

for_each(v.begin(),v.end(),print02())           //仿函数

transform  搬运容器到另一个容器中

a.  搬运前要先给目标容器开辟空间

b.  _Func可以是仿函数也可以是普通函数,其意义在于可以实现搬运同时修改数据

    v2.resize(v1.size());
    transform(v1.begin(), v1.end(), v2.begin(), _Func);

2.查找 

find 查找指定元素,找到返回指定元素迭代器,找不到返回结束迭代器

find(iterator beg,iterator end,value)

注意:查找自定义类型数据时,需要在类内重载==(如下)

bool operator==(const Person&p)
{
   if(//.............)
     {
          return true;
     }
}

find_if 按条件查找元素

find_if(iterator beg,iterator end, _Pred)                  //_Pred 函数或者谓词,作为条件

class GreaterThanFive
{
public:
	bool operator()(int a)
	{
		return a > 5;
	}
};

vector<int>::iterator it = find_if(v.begin(),v.end(),GreaterThanFive())

注意:查找自定义类型数据时,需要在类内重载== 

adjacent_find 查找相邻且重复元素

adjacent_find(iterator begin,iterator end)

若找到,返回第一个元素的迭代器;若未找到,返回end()

binary_search 查找指定元素是否存在

bool binary_search(iterator beg,iterator end,value)

查到,返回TRUE;否则返回FALSE

容器必须是有序序列(底层用二叉树实现)

count 统计元素个数

count(iterator beg,iterator end,value)

返回元素个数 int类型

统计自定义类型时,重载==(转到定义,可以明白原理)

count_if 按条件统计元素个数

count_if(iterator begin,iterator end, _Pred)                              _Pred 函数或谓词 作为条件

返回元素个数 int类型

3.排序 

sort  普通排序

sort(iterator begin,iterator end)   或  sort(iterator begin,iterator end , _Pred)

不填谓词,默认从小到大排序。

random_shuffle 洗牌 指定范围内元素随即调整顺序

random_shuffle(iterator begin,iterator end)

使用时,加入随机数种子,变为真随机。srand((unsigned int)time(NULL))

merge 两个容器元素合并,并存储到另一个容器中

merge(iterator beg1,iterator end1,iterator beg2,iterator end2, iterator dest)   

                                                                                               //最后一个参数是目标容器起始迭代器

两个待合并容器必须是有序的,合并后的容器也将是有序的。

需要提前给目标容器分配空间  v.resize(v1.size() + v2.size())

reverse 将容器内元素反转

reverse(iterator beg,iterator end)              1 2 3 4 5 ------------> 5 4 3 2 1

4. 拷贝和替换

copy 将元素拷贝到另一个容器中

copy(iterator beg,iterator end,iterator dest)

另一个容器也要提前分配空间 v2.resize(v1,size())

replace 指定范围内所有旧元素替换为新元素

replace(iterator beg,iterator end , oldvalue , newvalue)

replace_if 区间范围内满足条件的元素替换为新元素

replace(iterator beg,iterator end , _Pred , newvalue)

swap 互换两个容器的元素

同种类型容器

swap(容器1,容器2)

5.算数生成算法   #include<numeric>

accumulate 计算容器中数据之和

accumulate(iterator beg, iterator end ,  num)                   //num是起始累加值

fill 向容器中填充指定元素

fill( iterator beg,iterator end , num)                                  //num为填充值

6.集合算法

set_intersection 求两个容器的交集

两个集合必须是有序序列

提前给目标容器开辟空间 考虑极限情况: vTarget.resize(min(v1.size(),v2.size()))

vector<int>::iterator itEnd = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin())

返回值是交集结束位置迭代器,用itEnd接收。

遍历时:for_each(vTarget.begin() , itEnd , myPrint()) 若用vTarget.end() 则后面可能会有若干个0

set_union 求两个容器并集

两个集合必须是有序序列

提前给目标容器开辟空间 考虑极限情况: vTarget.resize(v1.size() + v2.size())

vector<int>::iterator itEnd =

set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin())

返回值是并集结束位置迭代器,用itEnd接收。

遍历时:for_each(vTarget.begin() , itEnd , myPrint()) 若用vTarget.end() 则后面可能会有若干个0

set_difference 求两个容器差集 

V1和V2的差集:V1中和V2不相交的部分

V2和V1的差集:V2中和V1不相交的部分

提前给目标容器开辟空间 考虑极限情况: vTarget.resize(max ( v1.size() , v2.size() ) )

vector<int>::iterator itEnd =

set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin())

返回值是差集 结束位置迭代器,用itEnd接收。

标签:容器,begin,end,string,iterator,STL,标准,int,模板
来源: https://blog.csdn.net/No_muffintop/article/details/121008474

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有