C++ 泛型算法简介
人不舒服写篇博客压压惊。。。
主要一些常见应用于容器的函数。这些算法一般位于头文件algorithm和头文件numeric中
只读算法
find 查找
accumulate 求和
equal 比较
例如:
//find(const_iterator,const_iterator,target);
//return const_iterator
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
auto it =find(nums.cbegin(), nums.cend(), 2);
auto it2=find(nums.cbegin(), nums.cend(), 6);
cout << *it << endl; //输出 2
cout << *(--it2) << endl;//输出 5
迭代器指示查找范围,返回查找结果迭代器,若查找失败则会返回nums.end(),即最后一个元素的后一个位置。
//accumulate(const_iterator,const_iterator,val);
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
int sum = accumulate(nums.cbegin(), nums.cend(), 0);
int sum2 = accumulate(nums.cbegin(), nums.cend(), 10);
cout << sum << endl;//输出 21
cout << sum2 << endl;//输出 22
迭代器指示求和范围,最后一个参数可以理解为初始值。
//equal(const_iterator1,const_iterator1,const_iterator2);
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
vector<int>nums2 = { 2, 2, 4, 3, 3, 1, 1, 3 };
vector<int>nums3 = { 2, 2, 4, 3, 3, 1, 1, 5 };
bool flag = equal(nums.cbegin(), nums.cend(), nums2.cbegin());
cout << flag << endl;//0
flag = equal(nums.cbegin(), nums.cend(), nums2.cbegin());
cout << flag << endl;//1
前两个迭代器指示第一个容器的比较范围,第三个迭代器表示第二个容器的起始位置,这里必须保证一点:
nums2.size()≥nums1.size()
否则会出如下错误:Debug Assertion failed
注:只读算法使用const迭代器,不改变容器的内容。
写入算法
顾名思义可以修改容器内容:
fill & fill_n 填充
copy 拷贝
replace 替代
例如:
//fill(iterator,iterator,val);
//fill_n(iterator,size,val);
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
fill(nums.begin(),nums.end(),0);//所有元素为0
fill_n(nums.begin(),nums.size(),1);//所有元素为1
fill_n(nums.begin(),nums.size()+1,1);//error
fill和fill_n无法改变容器的大小,当填充的范围超过容器的大小,则会报错:Debug Assertion failed
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
vector<int>nums2 = { 1,1,1,1,1,1,1,1 };
copy(nums2.begin(), nums2.end(), nums.begin());
参数分别是源范围和目的起始迭代器范围,保证目的容器的大小至少等于源容器大小。
vector<int>nums = { 2, 2, 4, 3, 3, 1, 1, 5 };
replace(nums.begin(),nums.end(),2,0);
将容器中值为2的元素替换为0
重排算法
sort 排序
unique 去重
我们知道这些泛型算法不改变容器的大小,所以上述去重实际上并不是删除重复元素,而是将不重复元素放到前面,而返回最后一个不重复元素之后的位置。我们需要使用容器自带的erase函数来真正去重
例如:
vector<int>nums = { 2, 2, 4, 3, 3, 1, 6,6,6,6};
sort(nums.begin(), nums.end());
auto end_unique = unique(nums.begin(), nums.end());
nums.erase(end_unique,nums.end());