Vector
- 需要头文件包含声明
include < vector >
- vector容器的下标是从0开始计数的,也就是说,如果vector容器的大小是n,那么,元素的下标是0~n-1
创建
一维数组:
vector <int> v;
空vectorvector<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个100v.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<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
用string对象初始化bitset对象
STL 方法
头文件:
算法部分主要由头文件< algorithm >
,< numeric >
和< functional >
组成
< algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
< numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
< functional>中则定义了一些模板类,用以声明函数对象
分类
STL中算法大致分为四类:
- 非可变序列算法:指不直接修改其所操作的容器内容的算法。
- 可变序列算法:指可以修改它们所操作的容器内容的算法。
- 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
- 数值算法:对容器内容进行数值计算
查找
-
查找算法:判断容器中是否包含某个值
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
: 对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。