泛型算法:
1、STL类库中提供的一些通用的非成员函数操作。算法是STL的苦力,是处理容器里面数据的方法,操作。这些算法可以操作在多种容器类型上,所以称为“泛型”,泛型算法不是针对容器编写,而只是单独依赖迭代器和迭代器操作实现。
#include <algorithm>
#include <numeric>
算法分类:
1、STL将算法库分为4组,前3个在#include<algorithm>头文件中描述,而第4个在#include<numeric>头文件中描述:
1、非修改式序列操作:不改变容器的内容,如find()、for_each()等。
2、修改式序列操作:可以修改容器中的内容,如transform()、random_shuffle()、copy等。
3、排序和相关操作:包括各种排序函数等,如sort()等。
4、通用数字运算:计算两个容器的内部乘积等。
|
for_each(): 将一个非修改式函数用于指定区间中的每个成员
find(): 在区间中查找某个值首次出现的位置
find_if(): 在区间中查找第一个满足断言测试条件的值
find_end(): 在序列中查找最后一个与另一个序列匹配的值。匹配时可使用等式或二元断言
find_first_of(): 在第二个序列中查找第一个与第一个序列的值匹配的元素。匹配时可使用等式或二元断言
adjacent_find(): 查找第一个与其后面的元素匹配的元素。匹配时可使用等式或二元断言
count(): 返回特定值在区间中出现的次数
count_if():
mismatch():
equal():
search():
search_n():
|
copy():
copy_backword():
swap():
swap_ranges():
iter_swap():
transform():
replace():
replace_if()
remove/remove_if
……
|
(3)排序和相关操作
sort():
stable_sort():
partial_sort():
nth_element():
lower_bound():
upper_bound():
equal_range():
……
|
(4)数字操作
accumulate(): 计算区间中的值的总和
inner_product(): 计算两个区间的内部乘积
partial_sum(): 将使用一个区间计算得到的小计复制到另一个区间中
adjacent_different(): 将使用一个区间的元素计算得到的相邻差集复制到另一个区间中
|
#include <iostream>
#include <vector>
#include <algorithm> //算法是处理容器中的元素的
using namespace std;
void print(vector<int>::value_type & v) //定义一元函数print,以容器中的元素类型为参数
{
v+=2; //传递的是元素引用,会修改容器中的元素值
cout<<v<<" ";
}
int main()
{
vector<int> vecInt = {1,2,3,4,5,6};
for_each(vecInt.begin(), vecInt.end(), print); //对vecInt中所有元素执行print操作
cout<<endl;
return 0;
}
//对于for_each而言,如果是vector<int> ob;这样的,此时调用for_each(ob.begin(), ob.end(), func);函数的时候,
//func函数的参数是int(或vector<int>::value_type)
//如果是map<int, string> obM;这样的,此时调用for_each(obM.begin(), obM.end(), func);函数的时候,
//func函数的参数是pair<int, string>这种数据类型的。
//总结:对于for_each的第三个参数而言,写函数的时候,函数的参数就是其中的迭代器指向的类型。
//对于vector<CMyString> 则是CMyString
//对于map<CMyString, string>则是由CMyString和string组成的,所以是pair<CMyString, string>
|
#include <iostream>
#include <algorithm>
#include <functional> //使用less<>类模板要用的头文件
#include <vector>
using namespace std;
int main()
{
vector<int> vecInt = {1,2,3,4,5,6};
less<int> lt; //创建less<int>类函数对象; 这个是重载了()操作符的类对象
replace_if(vecInt.begin(),vecInt.end(),bind1st(lt,3),7); //把vecInt中大于三的元素全部换成7
for(auto & elem : vecInt)
cout<< elem <<" ";
cout<<endl<<"------------------------------"<<endl;
vector<int> vecInt1 = {1,2,3,4,5,6};
replace_if(vecInt1.begin(),vecInt1.end(),bind2nd(lt,3),7); //把vecInt中小于3的元素全部换成7
for(auto & elem : vecInt1)
cout<< elem <<" ";
cout<<endl;
return 0;
}
|
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<string> vecStr;
vecStr.push_back("hello");
int i=0;
auto it=vecStr.begin(); //自动推断出这个变量的合理的数据类型而无需我们人为指定
//迭代器失效
for(; it != vecStr.end(); ++it)
{
cout<<"vecStr.capacity is :"<<vecStr.capacity() <<endl;
cout<< *it <<endl;
//上次push操作指针位置改变,迭代器到这里找不到地址,也就不能解引用
if(0==i)
{
vecStr.push_back("world"); //底层做了扩容的操作,迭代器it已经失效
cout<<"vecStr.push!"<<endl;
i=1;
}
}
}
这里的扩容不是在原有空间的基础上容量增加,而是从新申请一个更大的空间,然后把旧空间的内容拷贝到新申请的空间,释放原来的空间,所以迭代器遍历的时候扩容,迭代器++就找不到我们要找的内容,直接段错误
|
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vecInt;
vecInt.reserve(10);
cout<< vecInt.size() <<endl;
cout<< vecInt.capacity() <<endl;
for(int idx = 1;idx <=10; ++idx)
{
vecInt.push_back(idx);
}
vecInt[3] = vecInt[5] = vecInt[9] = 99;
for(auto & elem :vecInt)
cout<< elem << " ";
cout<<endl;
remove(vecInt.begin(),vecInt.end(),99);
//用指针指向的值是要删除的99的时候,再定义一个指针在容器后面寻找第一个不为99的元素,并替换当前的99,然后两个指针都向前+1
for(auto & elem :vecInt)
cout<< elem << " ";
cout<<endl;
}
此时的first不一定在最后一个元素位置 |
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vecInt;
for(int idx = 1;idx <= 10; ++idx)
vecInt.push_back(idx);
vecInt[3] = vecInt[5] =vecInt[9] = 99;
for(auto & elem : vecInt)
cout<< elem <<" ";
cout<<endl;
cout<<"------删除后------"<<endl;
//erase-remove 惯用法 --> 防止出现迭代器失效问题
vecInt.erase(remove(vecInt.begin(),vecInt.end(),99),vecInt.end());
//remove操作返回的是一个指针位置
for(auto & elem : vecInt)
cout<< elem <<" ";
cout<<endl;
return 0;
}
|