stl总结

序列容器:vector string 支持随机访问 deque双端效率高 有了栈队列 不支持随机访问
如果不知道用什么容器就用list 自己写sort函数 插入删除效率高,但排序慢
关联容器(自动排序):set(是否插入成功返回pair) map插入key-value  




STL宝典 台湾侯捷 语法上不难了,重点放在用上。
适配器中 typename的第二种用法,常用。函数自动推到
用的时候就不用写数据结构了,面向对象。
算法:这里的算法是普遍的算法,实现了算法和容器的分离
容器和算法通过迭代器无缝连接。stl的sort算法效率很高
stl中:
容器是一种class容器;是一种class template
算法是函数模板


vector v1;//1定义容器v1 盛放int类型
//2迭代器:相当于一个指针 vector::iterator it = v1.begin()
迭代器用来遍历容器的元素;迭代器:不重复的访问容器中的每个元素
迭代器也有类型: RAI
//3算法 算法和迭代器进行无缝连接 //int num1 = count(v1.begin(), v1.end, 3);//从头到尾的遍历 超找3的个数 
vector v1;//1定义容器v1 盛放Teacher类型//容器实现了 数据类型和算法的有效分离
***********************************************************************
#include "string"//不用考虑内存的问题
string 也是以0结尾 放在堆里
string重载了很多操作符[] at = 这就是string能用[]的原因,s[i]如果访问越界直接down, s.at(i)则会抛出异常
字符串string:有length()函数和size()函数 


1 字符串初始化:
string s1;调无参构造函数,创建空字符串。
string s1 = "aaaa";
string s2("2222");
string s3 = s2;//调用拷贝构造函数 初始化


2 字符串遍历:
只要是类似于遍历查找可用迭代器也可用[]数组的方式
数组方式:i < s1.length()
迭代器法:it != s1.end()
cout<<*this;


3 字符指针和string 的转换:
s1.c_str():s1===>char *用printf可打印出来
string s(str) char *===>s 隐式转换
即string的包容性比char *强
因为重载了[] 返回值是引用 所以可以当左值和右值,


4 string类字符串连接:
s1 = s1 + s2;//法1
s1.append(s2);//法2


5 字符串查找和替换:
第一次出现wbm的下标:int index=s1.find("wbm", 0);//位置下标从0开始
找不到返回-1
求出现次数 出现下标:(比较复杂)offindex != string::npos即不到最后
替换:s1.replace(offindex1, 3, "WBM"); 包括offindex1处的3个字符替换


6 截断和插入:
插入后原本该位置的元素后移
string::iterator it=find(s1.begin(), s1.end(), 'l');
s2.insert(0, "AAA");//头插法
s2.insert(s2.length(), "AAA");//尾插法


7 字符串比较:
s1.compare(s2);


8 string子串(常用):
int pos = email.find("@");
string username = email.substr(0, pos);
find+sbustr截取出目标字符串


s1定义一个字符串后 再给s1赋一个更长的值时,地址会发生变化。
string的字符串地址不能直接看,得用c_str()转为char *再强转才能看。
*********************************************************************
vector容器:
vector v2(arr, arr + sizeof(arr) / sizeof(int));
vector v3(v2.begin(),v2.end());
v2.assign(v1.begin(),v1.end());
vector v4(10,0); 10个0的vector
vector v5(v4);
v1.swap(v4);
单口的数组,单口(删除一个则移动)的动态数组,所以在尾部插入删除效率高
front返回的是元素不是迭代器,back是最后一个元素
动态增长:原来的满了,则申请更大的把原来的考过来,释放原来的空间(原来的空间则无效了,所以不要返回引用),
再插入新的。效率低                              (写动态数组  比较难)

1 reserve:
v.reserve(100000);因为一般情况下,当容量很大时(十万个),内存中的capacity会更大,而size仍是
十万。要想让内存中仍是十万个,就得预先留reserve十万个。预留位置不初始化,元素不可访问。
resize顾名思义只是对size重置(capcity该是多少还是多少不会变) 并完成了初始化,可直接访问
reserve 和 resize的capacity是实实在在地100000 而vector v(100000)这种的capacity是非常大的;

vector(v).swap(v);
巧用swap的精髓是:用已知的匿名对象初始化(swap也是初始化的一种)(只与size有关,不关capcity的事)已知的对象。
交换后匿名对象转正,原对象析构。

2 push_back
插入 pEnd指向的是最后一个元素的后一个位置

3 for_each()是遍历算法:头文件是algorithm。for_each(v1.begin(),v1,end(),MyPrint)     ¥for_each只是遍历!使用算法遍历¥¥¥¥¥¥¥¥¥¥¥ 
在MyPrint(*迭代器)函数中打印 其参数在这里是int类型                                   ¥¥sort只是排序
void MyPrint(int val){
cout << val << " ";
}
容器嵌套容器vector>v;
(*it).begin()

4 vector直接的push_back 则有非常大的可能size!=capcity。
而通过这种vector v1(10)的方式则两者是相等的

5 vector逆序遍历:
for (vector::reverse_iterator it = v1.rbegin(); it != v1.rend();it ++){
cout << *it << " ";
}
6 vector 初始化:
vector v1;
vector v2 = v1;//拷贝构造初始化v2

7 vector遍历 :
vector v1(10);//提前把内存分配好
v1[i]-----------------------------------------------vector容器支持随机访问,所以可以用[]来访问

8 pushback强化:
在尾部添加 长度也会变
void printV(vector &v)

9 vector的删除:
vector v1(10);//提前把内存分配好
v1.erase(v1.begin(), v1.begin() + 3);//区间删除  前三个
v1.erase(v1.begin());//根据元素位置删除
v1.erase(it);//当 删除迭代器所指向的元素的时候,eraser会自动的将it下移。


10 数组元素的 添加删除:
v1.size()长度;实时长度
v1.front()首部元素;v1.front() = 11;//函数返回值当左值 应该返回一个引用
v1.back()尾部元素;
v1.pop_back();//删除尾部元素

11排序操作:注意不是v.sort()!!!!!!!!
sort(vect.begin(), vect.end()); //此时相当于调用sort(vect.begin(), vect.end(), less() ); 435行
less是stl提供的仿函数。类似的仿函数还有
equal_to、not_equal_to、greater、less_equal、greater_equal。
******************************************************************少用
deque:双端数组 在两头效率高,在中间效率低
只要是pop是没有返回值的,删除时要非常慎重。
deque没有容量的概念:因为是分段连续,不象vector有整块连续的空间
看图:中控器结构 很像malloc出来的二级指针结构,实现比vector复杂
所以:若对deque容器排序,则把数据拷贝到vector中,排序后再拷回去。

也是RAI与vector一样都支持随机访问it=it+5。一般支持随机访问的都不需要写算法
因为是RAI 所以遍历时候参数最好写成const类型,相应的迭代器定义成const_iterator.
赋值操作:
d1.assign(10,10);10个10
评委打分的利器 +算法头文件+sort的回调函数                 ¥¥¥¥¥¥¥sort是排序¥¥¥¥¥¥¥
bool fun(Person p1, Person p2)
肠胃打分 竟然不写引用?!!!!void get_score(vector < Person>v) 给肠胃丢脸了
选手写到vector中,得分写到deque中 最后for_each打印出来
insert中 pos是迭代器 而不是位置
at(i);//返回索引i所指的数据,如果i越界,抛出out_of_range。

deque初始化:
deque d1; d1.assign(10, 100);
deque d1; int arr[] = { 6, 2, 8, 1, 0 };deque d2(arr,arr + sizeof(arr)/sizeof(int));

deque d1;
d1.push_back(1);
d1.push_front(4);
d1.front()头部元素
d1.back()尾部元素
d1.pop_front();
d1.pop_back();

查找5在数组下表的值:
deque::iterator it=find(d1.begin(), d1.end(), 5);
distance(d1.begin(), it)

排序:
bool MyCompare(int v1,int v2)
{return v1 < v2;}
sort(d.begin(), d.end(), MyCompare或写成less);

最值:
deque::iterator max =  max_element(d.begin(), d.end());
deque::iterator min =  min_element(d.begin(), d.end());

肠胃评分:那个案例有点难 写不出来

*************************************************配置器:以deque为基础上封装的***************
栈队列 非常常用!!!! 
因为有FILO规则 所以栈没有迭代器,不允许遍历 更不支持随机访问 
stack栈容器:入栈出栈都是发生在栈顶的位置
stack s;
入栈:s.push(1);
栈大小:s.size();
while (!s.empty())//出栈
{
int tmp = s.top();//获取栈顶元素
cout << tmp << endl;
s.pop();//弹出栈顶元素
}
栈的算法和数据类型的分离
*******************************************************************
queue队列模型:
FIFO 同栈
queue q;
q.push(1);
q.front();对头
q.size();对大小 从1开始的
while (!q.empty())//出对列
{
int tmp = q.front();
cout << tmp << " ";
q.pop();
}
队列的算法和数据类型的分离
**************************************与vector一样都非常常用*********************
如果不知道用什么容器 就用list
list双向(有迭代器只可++--)循环链表:不是随机访问迭代器  得自己写sort函数 插入删除效率高,但排序慢
//list是双向链表容器 可高效的插入删除元素 不可随机存取元素

删除一个节点 不影响list的iterator
按值删除 把所有值相同的元素全部删除L.remove(20);
指定位置删除 L.erase(it);

l.size()
l.push_back(i);//尾插法 
list不能随机访问:
it = it + 5; 这种用法不行,即list不支持速记访问容器,
list++可以
//结论1 链表的节点index序号是从0号位置开始的
//l.insert(l.begin(), 100);在3号位置插入元素 让原来的3号位置变4号位置。。。。。

list删除:
l.erase(it1, it2);//左闭右开的删除
l.remove(100);//删除所有100

list排序:为什么list可以“点出来sort”? 此sort非彼(谓词)sort!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
sort(L.begin(),L.end(),MyCompare); 这样是错的!
L.sort(); 默认的排序规则 从小到大 适用简单的数据类型int 
L.sort(MyCompare); 指定规则,从大到小
MyCompare返回值一定是bool 参数是容器装的类型(可以传引用)。
bool ComparePerson(Person& p1, Person& p2)
¥¥¥¥¥¥¥list不支持RAI,函数的sort得自己写¥¥¥¥¥¥¥¥¥

remove对象时,内部比较的是两个元素(复杂的概念)。 所以得重载对象的==
***************************************************************
优先级priority_queue队列:
priority_queue p1;//默认情况下 最大值优先级队列
priority_queue< int, vector, less > p2;//STL中提前定义好的函数:谓词
priority_queue, greater> p3;//最小值有限队列
p1.top()对头元素
p1.size()对大小
while (p1.size() > 0)//出对
{
cout << p1.top() << " ";
p1.pop();
}


***********上面是序列容器********以下是关联容器(自动排序)*********迭代器就是const_iterator
set关联容器:
set没有键值对 只有一个实值 查找效率高
二叉树 平衡二叉树(红黑二叉树) 可以自动排序 set不能插入重复的元素
所以不允许有相同的 所以不能修改某一个值(修改了其规则)所以是const_iterator
set容器:主要是仿函数和键值对,仿函数是stl的入门。
集合 元素是1 自动排序
默认从小到大排序
int tmp = rand();随机的插入
set1.insert(tmp);

删除集合:
while (!set1.empty())
{
set::iterator it = set1.begin();
cout << *it << " ";
set1.erase(set1.begin());
}

set set1;
set> set2;//相当于set1  set> set3;//从最大开始排序

排序:
对基本的数据类型这样排序 对于复杂的数据类型Teacher Student就需要自定义了需要仿函数(前面讲过重载())和函数对象
仿函数(函数对象):是一个结构体 里面重载() 返回bool 参数是const引用(或一般的参数)
struct MyCompare{
bool operator()(const Student &left, const Student &right){
if (left.age < right.age)//左边小 返回真 即从小到大排序年龄{
return true;}
else{return false;}}}


仿函数设置复杂类型的插入顺序;
插入一个元素是否成功,返回值是pair;


set set1;//仿函数用法 先写一个类重载 再插入
set1.insert(s5);其返回值类型是键值对pair: typedef pair _Pairib 实质就是模板
pair::iterator, bool> pair1 = set1.insert(s1);
pair是一个数据类型 iterator也是数据类型  iterator是迭代器的位置 bool迭代器的结果 就是一个键值对
所以可以把返回结果用一个兼职对类型来接
通过判断键值对里面bool的值,完成业务:
if (pair1.second == true)

两种方法创建pair:
pairp(10,20);
pairp2=make_pair("hello",10);



查找:
set::iterator it0=set1.find(5);查找5的位置,返回的是迭代器。找不到返回end()迭代器
int num1 = set1.count();统计某个元素的个数。
set::iterator it1= set1.lower_bound(5);//大于等于5的元素的迭代器
set::iterator it1= set1.uper_bound(5);//大于5的元素的迭代器
pair::iterator, set::iterator> mypair = set1.equal_range(5);返回两个迭代器it.first和it.second 
分别是lower_bound和uper_bound
set1.erase(5);//把5这个元素删掉
**************************************************************
multiset容器:
可插入重复的元素 
插入返回值是 一个迭代器(因为一定能插入成功)
18639357821 楼下那姑娘
**************************************************************                      !!set map插入的时候必须得有排序!!
map容器:是有键值对的 key不允许有相同的 根据key值排序                                因为是二叉树的模式,所以 当元素复杂    
时,必须自己写。所以自己写的函数必须写
                                                                                         到<>中。
插入4种方法:
map map1; 
map1.insert(pair(1, "teacher1"));
map1.insert(make_pair(3, "teacher3"));
map1.insert(map::value_type(5, "teacher5"));
map1[7] = "teacher7";
通过[]方式访问一个不存在的key,就会创建一个指向key的元素,value是默认值,插入到map中
虽然是[]仍不支持随机访问

插入返回值:
insert的返回的是pair 键值对

删除:
while (!map1.empty()){
map::iterator it = map1.begin();
cout << it->first << "\t" << it->second << endl;
map1.erase(it);}

查找:
m.find(2键值);返回迭代器位置map::iterator it
lower_bound uper_bound返回的是迭代器对组(上面的it)

pair< map::iterator, map::iterator> ret = m.equal_range(2);返回两个迭代器对组
分别是lower_bound和uper_bound
是迭代器对组:ret.first->first << ":" << ret.first->second 

排序:
指定map排序规则:默认都是key从小到大
写一个从大到小:就得写类重载()
class MyCompare{
public:
bool operator()(int v1,int v2){
return v1 > v2;}};
map m;
m.insert(make_pair(7, 2));

*********************************************************
注意 set容器排序是struct *
map容器排序用的是class                         *
其实都可以 class用的时候别忘了public *
set除了insert返回值是键值对。其他没有键值对         *
map本身就是键值对 *
复杂类型的排序问题必须用仿函数 *
*********************************************************
员工分组:
用multimap
员工放在vector中:
创建。
分组:编号组<部门编号,员工>
参数:员工组,编号组 遍历员工,产生编号分别插入到编号组
打印:参数是编号组
找到分组,返回迭代器,打印
名字分别是 vector 和 multimap
从名字应该能确定出来分配工作时怎么用:随机工作+ 顺序的插入(insert+make_pair)
srand((unsigned int)time(NULL));
int num=rand()%3; 生成的数比较随机 头文件是time.h
count+find遍历某部门信息


容器元素深拷贝浅拷贝问题:
vector v1;
Teacher类里面有一个 char *属性。
Teacher t1("mikedog", 41);
v1.push_back(t1);把t1拷贝了一份 存到容器中了
会出现浅拷贝(两个指针同时指向一块内存空间) 解决方法自己写拷贝构造函数 重载等号操作符
stl中所有容器是值寓意的,用户提供的元素必须能被拷贝。
——————————————————————————————————————————————————
对比:
线性的搜寻速度都比较慢
vector整块连续 deque分段连续
频繁插入删除:list公交车


也可以这样:
multimap map2;
map2.insert(make_pair("sale", p1));//sale 部门
按照字母的排列顺序 排序


**************************算法:函数对象(谓词)*********************************
算法头文件:#include functional numeric


函数对象(仿函数以前叫法)就是 在类中重载了(),使类对象像函数那样调用
函数对象是一个类,不是函数。  这就是函数对象与普通函数的本质区别!
1 函数指针在运行阶段才能确定函数调用。
2 而函数对象在编译阶段 确定函数调用 运行的时候就不用找了 效率高
3 函数没有类型
4 而函数对象是类 有类型,可以作为模板参数
5 函数对象超出了......  伪的全局变量
6 m.operator() 很有可能是内联编译 效率高



函数对象是属于类对象 能突破函数概念 能保持调用状态信息,这就是与普通函数的区别


函数对象:
以for_each为例for_each默认是一元函数对象可以追踪两次 当然可以通过函数适配器可以修改成二元 看475行
for_each遍历时:最后那个参数可以是 回调函数 也可以是函数对象:
for_each(v1.begin(), v1.end(), ShowElemt());//匿名函数对象 匿名仿函数 ShowElemt类中重载了类似92行的那个函数
for_each(v1.begin(), v1.end(), FuncShowElemt2);//通过回调函数 谁使用for_each谁去写回调函数的入口地址
for_each(v1.begin(), v1.end(), show1);??建议单步调试一遍 里面会调用类中的那个重载() 而不是外部的

/*template class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)迭代器 迭代器 函数对象 返回的是函数对象 
for_each返回的是函数对象 find返回的迭代器
 
for_each兰巴达表达式 
for_each(v.begin(), v.end(), [](int val)->void{cout << val << " "; });
 
谓词bool:返回值是bool的函数对象。
接受一个参数的函数,叫做一元函数,如果一元函数返回布尔值,则该函数成为一元谓词;
接受两个参数的函数为二元函数,如果返回一个布尔值,则该函数称为二元谓词。
一元谓词:函数参数1个 函数返回值是bool 可作为判断式
find_if:找到大于20的迭代器的位置。
struct GreaterThan20{
bool operator()(int val){
return val > 20;
}
};
find_if(v2.begin(), v2.end(), GreaterThan20());
_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)迭代器 迭代器 谓词 返回的是迭代器

二元谓词:函数参数2个 函数返回值是bool   133行
sort排序:
struct MyComparre{
bool operator()(int v1,int v2){
return v1 > v2;}};
sort(v1.begin(), v1.end(), MyCompare);

sort的第三个参数就是MyCompare二元谓词
看sort源代码:
void sort(_RanIt _First, _RanIt _Last, _Pr _Pred)

******************************************************
内件函数对象:
plus预定义好的函数对象 能实现不同类型的+运算
cout<()(30,10);//minus()是匿名对象 (30,10)则调用函数对象


//实现了 数据类型和函数算法的分离 是通过函数对象技术实现的
//怎么知道 plus是两个参数


//通过谓词求大于2的个数
int num2 = count_if(v1.begin(), v1.end(), IsGreat(2));
class IsGreat中有bool operator()(int &num)


//通过预定义的函数对象求大于2的个数
int num3 = count_if(v1.begin(), v1.end(), bind2nd(greater(),2));
//greater函数左参数来自容器中每一个数 右参数绑定成2
//通过预定义的函数对象求大于的个数  预定义+绑定 能实现分层
//看greater函数
/*template
struct greater
: public binary_function<_Ty, _Ty, bool>
{ // functor for operator>
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator> to operands
return (_Left > _Right);
}
};*/
*************************************************
函数对象适配器:绑定适配器的原因


for_each适配器:
for_each 的底层函数 跟两次_Func(*First);是一元函数对象,而不是二元函数对象!!!!!
如果要写成 void operator()(int v,int v1)只有通过绑定适配器:把二元函数对象转变为一元函数对象
1. 让自己编写的函数对象继承基类,如果是一元函数对象需要继承unary_function,
如果是二元函数对象继承binary_function
2. 函数对象operator()函数后增加 const
3. 使用bind2nd bind1st
bind2nd其实就将一个二元的函数对象转变为了一元函数对象
struct MyPrint : public binary_function < int, int, void > {
void operator()(int v, int v2) const{
cout << "v:" << v << " v2:" << v2 << endl;
cout << v + v2 << " ";}};
for_each(v.begin(), v.end(), bind1st(MyPrint(), 300));//遍历在原有的基础上额外加上300
bind2nd把300绑定为函数对象的第二个参数
bind1st把300绑定为函数对象的第一个参数


取反适配器:not1 not2
struct GreaterThan5 : public unary_function < int, bool > {
bool operator()(int v) const{
return v > 5;}};
vector::iterator it = find_if(v.begin(), v.end(), not1(bind2nd(greater(), 5)));//greater是二元函数对象
not1 对一元谓词取反  not2 对二元谓词取反


查找:find_if+1元谓词 经典的查找方式
排序:sort+2元谓词(回调函数)
sort(v.begin(),v.end(),not2(less()));//less也是2元函数对象


3 普通函数适配器:
把普通函数写成函数对象
遍历(条件遍历,在原来基础上加一个值):
发现绑定不了(因为普通函数不是类),所以把普通函数写成函数对象 加上ptr_fun即可
void MyPrint03(int val, int v2){
cout << val + v2 << " ";
}
for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint03), 100));
for_each(v.begin(), v.end(), bind2nd(MyPrint03, 100);//这样是错的!


4成员函数适配器:mem_fun和mem_fun_ref
for_each:可用回调函数打印 
void MyPrint04(Person& p){
cout << "全局函数:" << "Name:" << p.mName << " Age:" << p.mAge << endl;
}
for_each(v1.begin(), v1.end(), MyPrint04);

也可用成员函数打印,即成员函数适配器
for_each(v1.begin(), v1.end(), mem_fun_ref(&Person::ShowPerson));
加上mem_fun_ref即可
ref引用实体
***************************************************
算法:
一常用的遍历算法:
1 for_each算法         
说明了函数对象比函数的好处:
for_each返回的是谓词,用谓词来接,可以得到“全局信息”
for_each函数对象传递时 函数对象做函数参数 是值传递而不是引用传递                      ¥¥¥¥¥¥¥¥¥¥必经之路
inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
非引用传递时 实参初始化形参,形参做n多变化,都影响不到实参的值。没有半毛钱关系。但
可以通过返回值看信息。
//分清算法的返回值是迭代器还是谓词(函数对象)是算法的入门


函数对象怎么写?看源码中谓词的用法:_Func(*_First); 


不接返回值,void,传递引用 也可以传递形参 看需求




2 transform
transform(v.begin(), v.end(), vTarget.begin(), Transform1());
struct Transform1{
int operator()(int v){
return v + 100;
}
};
看源代码
返回值是:目标容器的迭代器。
看函数对象参数:确定谓词的返回值是int 参数是int
是等号操作而不是push_back 必须开辟内存


当然看源码函数对象的模式不仅有_Fn1 _Func(跟两次*_Dest = _Func(*_First);一元函数对象)
还有_Fn2 _Func(*_Dest = _Func(*_First1, *_First2);二元函数对象)这种格式,也不用考虑绑定适配器了
高中毕业06年 


二常用查找算法:
1 find 和 find_if 
当查找普通变量,不用写函数对象非常简单。看源码,返回值是迭代器。
当查找一个类时,不用写函数对象非常简单。得重载==
当查找对象指针时,得写函数对象。跟两次,得用find_if+绑定适配器
struct search_condition : public binary_function{
bool operator()(Person* p, Person* p2) const{
if (p->mName == p2->mName && p->mAge == p2->mAge){
return true;
}
return false;
}
};
Person* p = new Person("bbb", 20);
vector::iterator it = find_if(v.begin(), v.end(), bind2nd(search_condition(), p));
注意:
查找对象指针:
指针是一个值,不能按照地址的值查找。
看源码 返回值是bool
不绑定适配器只能判断固定的信息 如果把这个固定的参数变成可变的就得绑定适配器


2 相邻元素查找:adjacent_find 查找相邻重复元素 返回迭代器
3 二分查找:binary_search 返回bool
4 count count_if 统计元素的个数:
struct GreaterTwo{
bool operator()(int v){
return v > 2;
}
};
num = count_if(v.begin(), v.end(), GreaterTwo());





熟练的跟代码
查找对象(复杂的)
看源码,less<>
重载小于号
查找对象指针,更麻烦
Fn函数对象 
Pr谓词
replace_if 写谓词时候:
看源代码 返回值bool 一个参数




三 常用的排序算法:
1. merge 合并两个有序序序列 默认从小到大排序 现改为从大到小
struct MyCompare{
bool operator()(int v1,int v2){
return v1 > v2;
}
};
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin(), MyCompare());


2 sort算法:
使用sort算法 容器必须支持随机访问
sort默认从小到大排序
sort(v.begin(), v.end(),greater());
 
3 random_shuffle 洗牌,打乱容器中元素的次序:
random_shuffle(v.begin(),v.end());


4 reverse 反转
reverse(v.begin(),v.end());


四 常用的拷贝和替换算法:
1 copy:
v2.resize(v1.size());
copy(v1.begin(), v1.end(), v2.begin());
copy(v2.begin(), v2.end(), ostream_iterator(cout, " "));


2:replace 所有的都替换
    replace(v1.begin(), v1.end(), 2, 100);


bool MyCompare02(int v){  //所有大于2的全替换掉
return v > 2;             //老规矩 看源码 写谓词的参数 返回值
}
replace_if(v1.begin(), v1.end(),MyCompare02,100);


3 swap
vector v1;
vector v2;
swap(v1, v2);


五常用的算数生成算法:
accumulate 累加容器中元素:
int total = accumulate(v.begin(),v.end(),0);
fill填充:
fill(v.begin(), v.end(), 100);
六常用的集合算法:
求交集 set_intersection:
vector::iterator MyEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
copy(v3.begin(), MyEnd, ostream_iterator(cout, " "));
set_union 求并集
求差集 set_difference

























































你可能感兴趣的:(C++)