C++编程技巧——STL容器和方法

本文详细介绍了C++标准库STL中的核心组件,包括容器如vector、set、map、deque、list、stack和queue,以及算法如排序、查找、遍历和修改。还涵盖了特殊容器如unordered_set和unordered_map,以及算法如binary_search、lower_bound、upper_bound等。此外,文章还讨论了字符串、迭代器、算法的自定义比较函数和排序规则,以及如何使用STL进行高效的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vector

  • 需要头文件包含声明include < vector >
  • vector容器的下标是从0开始计数的,也就是说,如果vector容器的大小是n,那么,元素的下标是0~n-1

创建

一维数组:

  • vector <int> v; 空vector
  • vector<double> v(10); 指定容器的大小
    注意:元素的下标为0~9;另外,每个元素的值被初始化为0.0
  • vector<double> v(10,8.6) 创建一个具有n个元素的向量容器对象,每个元素具有指定的初始值
  • vector <int> v2(v1); 拷贝构造函数
  • vector<int> v2(v1.begin()+1,v1.begin()+3); 用已有vec的迭代器创建一个vector,复制 v1的一部分[_First, _Last),取头不取尾
  • v.assign(3,100) ; v中的元素为3个100
  • v.assign(ary,ary+5) ; 将数组中的元素依次赋给v,左闭右开
    二维数组:
  • vector<vector<int>> v(n, vector<int>(m)) 定义一个n行,m列的数组
  • v1.swap(v2) 交换v1和v2的内容

索引

v.front() ;			// v的最后一个成员
v.back(); 			// v的最后一个成员
v.at(4);				//v的第5个成员
v[4];					//v的第5个成员

添加

  • v.push_back(1) 在尾部追加新元素:
  • v[0]=1;以下标方式对某元素重新赋值
  • insert()方法可以在vector对象的任意位置前插入一个新的元素
v.insert(v.begin(),8);// 在最前面添加新元素,值为8
v.insert(v.end(),3);//在向量末尾添加新元素3
v1.insert(v1.begin()+1, v2.begin(),v2.end());//在v1的第1个位置插入v2的所有数据
v.insert(It,ary+2,ary+5); // 在指针it所指的位置,插入数组区间[arr+2,arr+5)
v.insert(It,2,20);// 在指针it所指的位置,插入两个20

删除

  • pop_back 删除最后一个元素
  • clear()方法则一次性删除vector中的所有元素。
  • erase()方法可以删除vector中迭代器所指的一个元素或一段区间中的所有元素
  • remove() :删除操作结束,v.size()不变。也就是说其实后面的元素没有完全删除
v.erase(v.begin()+2) // 删除元素v[2] 
v.erase(v.begin()+1,v.begin()+5) // 删除闭区间左闭右开
v.erase(v.begin()+1,v.end()-2) // 
//删除vector 中值为3的元素
for(it=v.begin();it!=v.end(); )
{
	if(*it==3)
		it=v.erase(it);
	else 
		++it;
}
// 删除所有的偶数元素
for(vector<int>::iterator it=vec.begin(); it!=vec.end();it++)
{
	if(*it %2==0){
		it=vec.erase(it);
		it--;
	}
}

大小

  • v.size()方法可以返回向量的大小,即元素的个数。
  • v.empty()方法返回向量是否为空, 若为空返回1。
  • v.capacity() 同v.size()
  • v.resize(4) 改变大小,只保留前4个元素
  • v.resize(7,100) 扩充到7个元素,用100补全

排序

  • reverse算法可将向量中某段迭代器区间元素反向排列
  • sort算法要求使用随机访问迭代器进行排序,在默认的情况下,对向量元素进行升序排列;还可以自己设计排序比较函数,然后,把这个函数指定给sort算法
#include <algorithm>
reverse(v.begin(),v.end()); //降序排列
sort(v.begin(),v.end());//升序排列
sort(v.begin(),v.end(),Comp); //自定义排序

遍历

正向遍历

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

反向遍历

vector<int>:: reverse_iterator rit;
for(rit=v.rbegin();rit!=v.rend();rit++){
	cout<< *rit<<endl;
}

String

创建

  • 创建了字符串对象s, s是一个空字符串,其长度为0: string s

赋值

  • 直接给字符串对象赋值: s="hello"
  • 字符指针赋给一个字符串对象
#include <string>
string s;
char ss[5000];
scanf("%s",&ss);
s=ss

添加

  • +操作符
  • append()
  • insert()方法把一个字符插入到迭代器位置之前
s=s+'a'
s=s+"abc"
s.append("abc")
s.insert(s.begin(),'p') //在字符串的最前面添加字符‘p’

访问

  • 用下标方式随机访问string对象的元素,下标是从0开始计数的。例如: s[0]

删除

  • 清空一个字符串,则直接给它赋空字符串即可。
  • erase()方法删除迭代器所指的那个元素或一个区间中的所有元素

长度

  • s.length()返回字符串的长度
  • s.empty()方法,可返回字符串是否为空

替换

  • s.replace(3,2,"good") : 将字符串s的第四个字符开始,连续的2个字符替换成“good”

搜索

  • find()方法可查找字符串中的第一个字符元素(char,用单引号界定)或者子串(用双引号界定),如果查到,则返回下标值(从0开始计数),如果查不到,则返回s.end()
s.find('c')// 查找第一个字符c出现的位置
s.find("abc")//查找第一次出现字符串的位置
find (str.begin(), str.end(), 'a') 

比较大小

  • compare()方法与其他字符串相比较。如果它比对方大,则返回1;如果它比对方小,则返回-1;如果它与对方相同(相等),则返回0
s.compare("hi")

反转

  • reverse()方法可将string对象迭代器所指向的一段区间中的元素(字符)反转
reverse(s.begin(),s.end());// 降序排序
  • 使用反向迭代器 rbegin() rend()
string rev = string(str.rbegin(),str.rend()); 

Set

  • set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点左子树的高度与右子树的高度相等.
  • 不会重复插入相同键值的元素,而采取忽略处理
  • 平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque和list等容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值由小到大的顺序排列
  • 对于set容器中的键值,不可直接去修改。因为如果把容器中的一个键值修改了,set容器会根据新的键值旋转子树,以保持新的平衡,这样,修改的键值很可能就不在原先那个位置上了

创建

#include <set>
set<int> s;
set<int, greater<int> > s2;
multiset<int, less<int> > ms1;
set<int> s3(ary,ary+3);
set<int, less > s4(s1);

插入

  • 采用insert()方法把元素插入集合中去,插入的具体规则在默认的比较规则下,是按元素值由小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。使用前向迭代器对集合中序遍历,其结果正好是元素排序的结果。
s.insert(8);
s.insert(4);
s.insert(2);
s.insert(5);
// 默认升序插入
set<int> iterator it;
for(it=s.begin();it!=s.end();it++)
 	cout<<*it<<" ";
 //2 4 5 8 

// 自定义排序
set<int, myComp> s;
//当元素不是结构体:自定义函数myComp, 重载“()”操纵符
struct myComp
{
	bool operator()(const int&a, const int &b)
	{
		if(a!=b)  return a>b;
		else return a>b;
	}
}

//当元素是结构体:直接把比较函数写在结构体内
struct Info
{
	string name;
	float score;
	bool operator <(const Info &a) const
	{
		return a.score<score;
	}
}

遍历

set<int> :: reverse_iterator rit;
for(rit=s.rbegin();rit!=s.rend();rit++)
	cout<<*rit<<" ";
// 8  5 4 2 

删除

s.erase(6) // 删除键值为6的元素
s.clear();// 清空集合

查找

使用find()方法对集合进行搜索,如果找到查找的键值,则返回该键值的迭代器位置,否则,返回集合最后一个元素后面的一个位置,即end()

// 用find 函数查找
set<int> :: iterator it;
it =s.find(6); // 查找键值为6的元素
if(it != s.end())  // 找到
	cout<<*it<<endl;
else
	cout<<"not found"<<endl;
// 用count函数查找
int n = s.count(2);  // 返回0或者1

范围

 *c.lower_bound(3)
 *c.upper_bound(3)
 *c.equal_range(3).first
 *c.equal_range(3).second

Multiset

mutiset 与 set一样,唯一不同的是multiset 允许重复元素的插入。

插入

ms.insert() : 允许重复插入键值相同的元素

#include <set>
multiset<string> ms;
ms.insert("abc");

删除

  • erase()方法可以删除multiset对象中的某个迭代器位置上的元素、某段迭代器区间中的元素、键值等于某个值的所有重复元素,并返回删除元素的个数
  • 采用clear()方法可以清空元素。

查找

  • find()方法查找元素,如果找到,则返回该元素的迭代器位置(如果该元素存在重复,则返回第一个元素重复元素的迭代器位置);如果没有找到,则返回end()迭代器位置

unordered_set

#include < unordered_set >
因为内部实现了哈希表,因此其查找速度非常的快,其元素的排列顺序是无序的。
unordered_set的用法和set是一样的

Map

  • map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系
  • map映照容器的数据结构也是采用红黑树来实现的,插入元素的键值不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。

创建

# include <map>
map<string, float> m;

typedef map<int, char, less<int> > M;
M m1;
M m2(m1);
M m3(m2.begin(),m2.end())

插入

m["jack"]=1;
m.insert(pair<string,float>("Jack",300.5));
m1.insert(m2.begin(),m2.end());

遍历

map<string,float> :: iterator it;
for(it=m.begin();it!=m.end();it++)
 cout<<(*it).first<<" "<<(*it).second<<endl;

删除

  • m.erase(28) : 删除键值为28的元素
  • m.clear() : 清空map 映照容器

反向遍历

map<int,char> :: reverse_iterator rit;
for(rit= m.rbegin();rit!=m.rend();rit++){
	cout<<(*rit).first<<" : "<<(*rit).second<<endl;
}

查找

  • find()方法来搜索某个键值,如果搜索到了,则返回该键值所在的迭代器位置,否则,返回end()迭代器位置
map<char,int> mymap;
it = mymap.find('b');

自定义比较函数

  • map<int, char,myComp> : 按照键值由小到大放入黑白树中。
  • map<Info,int> m; : 按照Info 结构体中重载的“<”排序

Multimap

#include
multimap与map基本相同,唯独不同的是,multimap允许插入重复键值的元素

创建

multimap<string,double> m;

插入

可以重复插入元素,插入元素需要使用insert()方法。
m.insert(pair<string,double>("jack",200.6));

删除

  • erase()方法,可删除某个迭代器位置上的元素、等于某个键值的所有重复元素、一个迭代器区间上的元素。
  • clear()方法可将multimap容器中的元素清空。

查找

由于multimap存在重复的键值,所以find()方法只返回重复键值中的第一个元素的迭代器位置,如果没有找到该键值,则返回end()迭代器位置

unordered_map

#include < unordered_map >
因为内部实现了哈希表,因此其查找速度非常的快,其元素的排列顺序是无序的。
unordered_map的用法和map是一样的

Deque

其他用法同vector, 但是deque可以在队头进行插入和删除

// 创建
deque<int> d1;
deque<int> d2(10);
deque<int> d3(10,0);
deque<string> d5(d4);
//赋值
d.assign(ary,ary+5);
d1.swap(d2);
// 索引
d.at(1) = 200;
d.back()
d.front()
//遍历
deque<int>::iterator It = d.begin();
d.end()
deque::reverse_iterator r = d.rbegin();
while ( r != d.rend() )
// 插入
d.push_back(n1);
d.push_front(n1);
d.insert(It,5);
d.insert(It,ary+2,ary+5);
d.insert(It,2,20);
// 删除
d.pop_front(); 
d.pop_back();
d.clear();
d.erase(It,It+2);
// 大小
d.size();
d.empty() 
d.resize(4);

List

  • list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都是极快速的。
  • list的每个节点有三个域:前驱元素指针域、数据域后继元素指针域。
  • 由于list对象的节点并不要求在一段连续的内存中,所以,对于迭代器,只能通过“++”或“–”的操作将迭代器移动到后继/前驱节点元素处。而不能对迭代器进行+n或-n

创建

list<int> l;  //创建空链表
list<int> l(10); // 创建指定个数的链表
l.assign(ary,ary+5); // 1 2 3 4 5
l.assign(3,100); // 100 100 100
li1.swap(li2);

索引

  • l.back()
  • li.front()

插入

  • push_back()方法往尾部插入新元素,链表自动扩张。
  • push_front()方法往首部插入新元素,链表自动扩张。
  • insert()方法往迭代器位置处插入新元素,链表自动扩张。注意,迭代器只能进行“++”或“- -”操作,不能进行+n或-n的操作,因为元素的位置并不是物理相连的.

删除

  • remove()方法删除链表中一个元素,值相同的元素都会被删除
  • pop_front()方法删除链表首元素
  • pop_back()方法删除链表尾元素
  • l.pop_back()
  • erase()方法删除迭代器位置上的元素
  • clear() 方法清空链表

查找

  • find()查找算法可以在链表中查找元素,如果找到该元素,返回的是该元素的迭代器位置;如果没有找到,则返回end()迭代器位置.
it= find(l.begin(),l.end(),5);

合并

 list1.sort();
 list2.sort();
 list1.merge(list2); //合并完成后,list2变为空,list1升序排列

排序

  • sort()方法可以对链表元素进行升序排列
l.sort();
li.sort(greater<int>()); //降序
li.sort(less<int>()); // 升序

去重

unique()方法可以剔除连续重复元素,只保留一个。

l.unique();

合并并去重

li1.sort();
 li2.sort();
 li1.merge(li2);
 li1.unique();

遍历

list<int>::iterator It = li.begin();
 while ( It != li.end() )
 cout << *(It++) << " ";

反转

  • l.reverse(); 反转

拼接

li1.splice(li1.end(),li2);
li1.splice(li1.end(),li3,li3.begin(),li3.end());
li1.splice(li1.begin(),li4,It);

Stack

stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行。插入元素的一端称为栈顶(StackTop),而另一端则称为栈底(StackBottom)。插入元素叫入栈(Push),元素的删除则称为出栈(Pop)

# include <stack>
// 创建一个堆栈
stack<int> s;
//入栈
s.push(1);
// 出栈
s.pop();
// 元素数量
s.size();
// 判空
s. empty();
// 栈顶元素
 s.top();

Queue

  • queue队列容器是一个先进先出(First In FirstOut, FIFO)的线性存储表,元素的插入只能在队尾,元素的删除只能在队首
  • queue队列具有入队push()(即插入元素)、出队pop()(即删除元素)、读取队首元素front()、读取队尾元素back()、判断队列是否为空empty()和队列当前元素的数目size()这几种方法。

Priority_queue

  • 只能从队尾插入元素,从队首删除元素。队列中最大的元素总是位于队首出队时,而是将当前队列中最大的元素出队。

  • 元素的比较规则默认为按元素的值由大到小排序;当然,可以重载“<”操作符来重新定义比较规则。

  • 优先队列包含入队push()(插入元素)、出队pop()(删除元素)、读取队首元素top()、判断队列是否为空empty()和读取队列元素数量size()等方法。

  • 元素是结构体类型:重载“<”操作符来定义优先级

// 对于Pair 的比较,先比较第一个元素,第一个相等比较第二个
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main() 
{
    priority_queue<pair<int, int> > a;
    pair<int, int> b(1, 2);
    pair<int, int> c(1, 3);
    pair<int, int> d(2, 5);
    a.push(d);
    a.push(c);
    a.push(b);
    while (!a.empty()) 
    {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }
}
/*
输出:
2 5
1 3
1 2
*/
//自定义结构体
#include<iostream>
#include<queue>
using namespace std;
 
struct node{
	int x;
	int y;
	node(){}
	node(int _x,int _y):x(_x),y(_y){}
	
};
struct cmp1{
	bool operator ()(node a,node b){
			if(a.x==b.x){
				return a.y<b.y;
			}
			return a.x<b.x;
	}
};
 
struct cmp2{
	bool operator ()(node a,node b){
			if(a.x==b.x){
				return a.y>b.y;
			}
			return a.x>b.x;
	}
};
	
int main(){
	priority_queue<node,vector<node>,cmp1> pq1;
	priority_queue<node,vector<node>,cmp2> pq2;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			pq1.emplace(i,j);   //emplace构造一个对象node 
			pq2.emplace(i,j);
		}
	}
	printf("pq1 从大到小\n");
	while(!pq1.empty()){
		printf("%d %d\n",pq1.top().x,pq1.top().y);
		pq1.pop();
	}	
	printf("pq1 从小到大\n");
	while(!pq2.empty()){
		printf("%d %d\n",pq2.top().x,pq2.top().y);
		pq2.pop();
	}
	return 0;
}
  • 元素不是结构体类型:重载“()” 来定义优先级
//方法1 使用仿函数
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;
//方法2 自定义类型
#include <iostream>
#include <queue>
using namespace std;

//方法1
struct tmp1 //运算符重载<
{
    int x;
    tmp1(int a) {x = a;}
    bool operator<(const tmp1& a) const
    {
        return x < a.x; //大顶堆
    }
};

//方法2
struct tmp2 //重写仿函数
{
    bool operator() (tmp1 a, tmp1 b) 
    {
        return a.x < b.x; //大顶堆
    }
};

int main() 
{
    tmp1 a(1);
    tmp1 b(2);
    tmp1 c(3);
    priority_queue<tmp1> d;
    d.push(b);
    d.push(c);
    d.push(a);
    while (!d.empty()) 
    {
        cout << d.top().x << '\n';
        d.pop();
    }
    cout << endl;

    priority_queue<tmp1, vector<tmp1>, tmp2> f;
    f.push(c);
    f.push(b);
    f.push(a);
    while (!f.empty()) 
    {
        cout << f.top().x << '\n';
        f.pop();
    }
}
/*
输出:
3
2
1

3
2
1
*/

Bitset

#include <bitset>
using std::bitset;

定义

bitset<n> b;	          //b有n位,每位都为0
bitset<n> b(u);	          //b是unsigned long型u的一个副本
bitset<n> b(s);	          //b是string对象s中含有的位串的副本
bitset<n> b(s, pos, n);	  //b是s中从位置pos开始的n个位的副本

初始化

// 用unsigned 值初始化bitset对象
// bitvec1 is smaller than the initializer
bitset<16> bitvec1(0xffff);          // bits 0 ... 15 are set to 1
// bitvec2 same size as initializer
bitset<32> bitvec2(0xffff);          // bits 0 ... 15 are set to 1; 16 ... 31 are 0
// on a 32-bit machine, bits 0 to 31 initialized from 0xffff
bitset<128> bitvec3(0xffff);         // bits 32 through 127 initialized to zero

参考 bitset

用string对象初始化bitset对象

STL 方法

头文件
算法部分主要由头文件< algorithm >< numeric >< functional >组成

< algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
< numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
< functional>中则定义了一些模板类,用以声明函数对象
分类
STL中算法大致分为四类:

  1. 非可变序列算法:指不直接修改其所操作的容器内容的算法。
  2. 可变序列算法:指可以修改它们所操作的容器内容的算法。
  3. 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
  4. 数值算法:对容器内容进行数值计算

查找

  • 查找算法:判断容器中是否包含某个值
    adjacent_find: 在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的 ForwardIterator。否则返回last。重载版本使用输入的二元操作符代替相等的判断。
    binary_search: 在有序序列中以二分的方法查找value,找到返回true。
    count: 利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。
    count_if: 利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数。
    find: 利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的 一个InputIterator。
    find_end: 在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一 个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代 替等于操作。
    find_first_of: 在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使用了用户自定义操作符。
    find_if: 使用输入的函数代替等于操作符执行find。
    search: 给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位置,查找失败指向last1。重载版本使用自定义的比较操作。
    search_n:在指定范围内查找val出现n次的子序列。重载版本使用自定义的比较操作。
    lower_bound.(k)返回一个迭代器,指向第一个值不小于k的元素
    upper_bound(k) 返回一个迭代器,指向第一个值大于k的元素
    equal_range(k) 返回一个迭代器pair,表示值等于k的元素的范围。若k不存在,pair两个成员均等于end()–尾迭代器

  • 如果所查找值在容器中,lower_bound返回的迭代器将指向第一个具有给定值的元素,而upper_bound返回的迭代器指向最后一个匹配给定值的元素之后的位置。

  • 如果元素不在容器中,则lower_bound和upper_bound会返回相等的迭代器----指向一个不影响排序的值插入位置

binary_search/ lower_bound/upper_bound常见用法

// 二分查找,成功返回1,否则返回0
binary_search(a,a+9,5);//查找成功,返回
// 打印multimap容器中所有关键字为2的元素
	for (auto beg = map.lower_bound(2), end = map.upper_bound(2); beg!= end; beg++)
		cout << beg->second << endl;
//打印vector数组中大于等于5的元素范围
	vector<int> v = { 1,2,3,4,5,6,7,8 }; //这里数组v最好是有序的
	for (auto beg = lower_bound(v.begin(), v.end(),5); beg != v.end(); beg++)
		cout << *beg <<" " <<ends;
	cout << endl;
// 在vector数组中查找存在的元素
	vector<int> v = { 1,2,3,4,5,6,7,8}; //这里数组v最好是有序的
	auto beg = lower_bound(v.begin(), v.end(), 5), end = upper_bound(v.begin(), v.end(), 5);
		cout << *beg <<" " <<ends;
		cout << endl<<*end << endl;
	cout << endl;

自定义比较函数

// 结构体
struct point{
	int x;
	int y;
}
bool cmp(point a, point b){
    return a.x < b.x;
}
lower_bound(a, a + 5, point(1, 1000), cmp)

count/countif 常见用法

// 返回元素值为target的元素个数
int num=count(vector1.begin(),vector2.begin(),target);  
// 返回满足comp函数的元素个数
bool comp(int num)
{
    return num%2;
}
count_if(V.begin(),V.end(),comp)  // 输出vector 中奇数的个数

find&find_if&find_if_not

// find查找等于指定值的迭代器,找不到返回v.end()
it = find (v.begin(), v.end(), 30); // vector中查找
it=s.find(40)  // set中查找
it=m.find(a) //通过键值在map中查找
// find_if
bool IsEven (int i)
{
  return ((i%2)==0);
}
 it = find_if (v.begin(), v.end(), IsEven); // 查找第一个为偶数的位置
 it = find_if_not (v.begin(), v.end(), IsEven); // 查找第一个为奇数的位置

search & search_n&find_end

// search  无op版本
auto it = search(c1.begin(), c1.end(), c2.begin(), c2.end()); // 返回vector::c1序列中c2首次出现的位置,若没有则返回c1.end()
// search 有自定义op版本
auto it = search(c1.begin(), c1.end(), c2.begin(), c2.end(),check() ); // 返回vector::c1序列check()之后,c2首次出现的位置,若没有则返回c1.end()
struct check
{
	bool operator()(int i, bool j)
	{
		if (j)  //j=1代表我要偶数
		{
			return (i % 2) == 0;
		}
		else
		{
			return (i % 2) == 1;
		}
	}
};

// search_n  无op
auto it = search_n(c1.begin(),c1.end(),2,3); // 回指向区间[beg,end)中第一组连续2个与3值相同的元素区间的首元素位置的迭代器,未发现则返回end
//  search_n  有op
auto it = search_n(c1.begin(),c1.end(),2,3,greater<int>());//回指向区间[beg,end)中第一组连续2个大于3区间的首元素位置的迭代器,未发现则返回end

//find_end 无op
it = find_end(myvector.begin(), myvector.end(), myarr, myarr + 3); //最后一个myarr在myvector中起始位置
//find_end 有op
bool mycomp1(int i, int j) { //即在 myvector 容器中找到最后一个子序列,该序列中的元素能分别被arr中的元素整除。
    return (i%j == 0);
}
it = find_end(myvector.begin(), myvector.end(), myarr, myarr + 3,mycomp2()); //

排序

  • 排序和通用算法:提供元素排序策略
    inplace_merge: 合并两个有序序列,结果序列覆盖两端范围。重载版本使用输入的操作进行排序。
    merge: merge() 函数用于将 2 个有序序列合并为 1 个有序序列,前提是这 2 个有序序列的排序规则相同(要么都是升序,要么都是降序)。并且最终借助该函数获得的新有序序列
    nth_element: 将范围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。重 载版本使用自定义的比较操作。
    partial_sort: 对序列做部分排序,被排序元素个数正好可以被放到范围内。重载版本使用自定义的比较操作。
    partial_sort_copy: 与partial_sort类似,不过将经过排序的序列复制到另一个容器。
    partition: 对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。
    random_shuffle: 对指定范围内的元素随机调整次序。重载版本输入一个随机数产生操作。
    reverse: 将指定范围内元素重新反序排序。
    reverse_copy: 与reverse类似,不过将结果写入另一个容器。
    rotate: 将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。
    rotate_copy: 与rotate类似,不过将结果写入另一个容器。
    sort: 以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
    stable_sort: 与sort类似,不过保留相等元素之间的顺序关系。
    stable_partition: 与partition类似,不过不保证保留容器中的相对顺序。

merge & inplace_merge

//将 [first,first+5) 和 [second,second+6) 合并为 1 个有序序列,并存储到 myvector 容器中。
merge(first, first + 5, second, second + 6, myvector.begin());
    //将 [first,first+5) 和 [first+5,first+11) 合并为 1 个有序序列。
    inplace_merge(first, first + 5,first +11);

sort&is_sorted

// sort
sort(myvector.begin(), myvector.begin() + 4);
sort(myvector.begin(), myvector.begin() + 4, std::greater<int>()); 

bool mycomp(int i, int j) {
    return (i < j);
}
sort(myvector.begin(), myvector.end(), mycomp);

// is_sorted 该函数会返回一个 bool 类型值,即如果 [first, last) 范围内的序列符合我们指定的排序规则,则返回 true;反之,函数返回 false。
is_sorted(myvector.begin(), myvector.end(),mycomp)
is_sorted(mylist.begin(), mylist.end())

particial_sort & nth_element
partial_sort(),nth_element() 函数只适用于 array、vector、deque 这 3 个容器。

nth_element() 函数可以从某个序列中找到第 n 小的元素 K,并将 K 移动到序列中第 n 的位置处。不仅如此,整个序列经过 nth_element() 函数处理后,所有位于 K 之前的元素都比 K 小,所有位于 K 之后的元素都比 K 大。

    //以默认的升序排序作为排序规则,将 myvector 中最小的 4 个元素移动到开头位置并排好序
    std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end());
    
    bool mycomp1(int i, int j) {
    return (i > j);
     }
  // 以指定的 mycomp2 作为排序规则,将 myvector 中最大的 4 个元素移动到开头位置并排好序
    std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end(), mycomp2());

删除和替换

  • 删除和替换算法
    copy: 复制序列
    copy_backward: 与copy相同,不过元素是以相反顺序被拷贝。
    iter_swap: 交换两个ForwardIterator的值。
    remove: 删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove和 remove_if函数。
    remove_copy: 将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置。
    remove_if: 删除指定范围内输入操作结果为true的所有元素。
    remove_copy_if: 将所有不匹配元素拷贝到一个指定容器。
    replace: 将指定范围内所有等于vold的元素都用vnew代替。
    replace_copy: 与replace类似,不过将结果写入另一个容器。
    replace_if: 将指定范围内所有操作结果为true的元素用新值代替。
    replace_copy_if: 与replace_if,不过将结果写入另一个容器。
    swap: 交换存储在两个对象中的值。
    swap_range: 将指定范围内的元素与另一个序列元素值进行交换。
    unique: 清除序列中重复元素,和remove类似,它也不能真正删除元素。重载版本使用自定义比较操作。
    unique_copy: 与unique类似,不过把结果输出到另一个容器。
    排列组合算法(2个):提供计算给定集合按一定顺序的所有可能排列组合
    next_permutation: 取出当前范围内的排列,并重新排序为下一个排列。重载版本使用自定义的比较操作。
    prev_permutation: 取出指定范围内的序列并将它重新排序为上一个序列。如果不存在上一个序列则返回false。重载版本使用 自定义的比较操作。

算术

  • 算术算法
    accumulate: iterator对标识的序列段元素之和,加到一个由val指定的初始值上。重载版本不再做加法,而是传进来的 二元操作符被应用到元素上。
    partial_sum: 创建一个新序列,其中每个元素值代表指定范围内该位置前所有元素之和。重载版本使用自定义操作代 替加法。
    inner_product: 对两个序列做内积(对应元素相乘,再求和)并将内积加到一个输入的初始值上。重载版本使用用户定义 的操作。
    adjacent_difference: 创建一个新序列,新序列中每个新值代表当前元素与上一个元素的差。重载版本用指定二元操作计算相 邻元素的差。

生成和异变

  • 生成和异变算法
    fill: 将输入值赋给标志范围内的所有元素。
    fill_n: 将输入值赋给first到first+n范围内的所有元素。
    for_each: 用指定函数依次对指定范围内所有元素进行迭代访问,返回所指定的函数类型。该函数不得修改序列中的元素。
    generate: 连续调用输入的函数来填充指定的范围。
    generate_n: 与generate函数类似,填充从指定iterator开始的n个元素。
    transform: 将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一 个元素来自输入的另外一个序列。结果输出到指定容器。

关系

  • 关系算法
    equal: 如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操 作符。
    includes: 判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回 true。重载版本使用用户输入的函数。
    lexicographical_compare: 比较两个序列。重载版本使用用户自定义比较操作。
    max: 返回两个元素中较大一个。重载版本使用自定义比较操作。
    max_element: 返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。
    min: 返回两个元素中较小一个。重载版本使用自定义比较操作。
    min_element: 返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。
    mismatch: 并行比较两个序列,指出第一个不匹配的位置,返回一对iterator,标志第一个不匹配元素位置。 如果都匹配,返回每个容器的last。重载版本使用自定义的比较操作。

集合

  • 集合算法
    set_union: 构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。
    set_intersection: 构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。
    set_difference: 构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用 自定义的比较操作。
    set_symmetric_difference: 构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。
  • 堆算法
    make_heap: 把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
    pop_heap: 并不真正把最大元素从堆中弹出,而是重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的 back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。
    push_heap: 假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把 元素插入容器后。重载版本使用指定的比较操作。
    sort_heap: 对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zyw2002

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

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

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

打赏作者

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

抵扣说明:

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

余额充值