标准库模板: Algorithms
头文件<algorithm>定义了一系列特别设计用于元素范围的函数。
范围是可以通过迭代器或指针访问的任何对象序列,例如数组或某些STL 容器的实例。但请注意,算法直接通过迭代器对值进行操作,不会以任何方式影响任何可能容器的结构(它永远不会影响容器的大小或存储分配)。
在开始之前,首先介绍下一些模板的知识,本文在介绍具体函数之前,先把函数总览列了出来,如果读者不想看全部内容,可以检索定位到自己喜欢的函数,直接查看。在查看本文章之前需要读者具备一定的 vector 知识。本文作者只写了algorithm 中常用的一些函数,如果读者有其他需要,可以在博客中留言,博主会为读者添加
vector 参考链接: https://blog.csdn.net/qq_41291253/article/details/89840185
函数模板与类模板
模板是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了代码的重用。所谓函数模板,实际上就是建立一个通用函数,其函数返回类型和形参类型不具体制定,用一个虚拟的类型来代表。
函数模板声明格式如下:
template <typename/class 类型参数>
返回类型 函数名(模板形参表)
{
函数体
}
//求最大值函数 max()定义成函数模板
template <typename T>
T max(T x, T y)
{ return(x > y) ? x : y; }
//使用方式,直接函数名调用
int x1, y1;
double x2, y2;
max(x1, y1);
max(x2, y2);
类模板
template <class 类型参数>
class 类名
{
类成员声明
};
//求三个数之和
template <class T>
class Three
{
public::
Three(T a, T b, T c)
{ x = a; y = b; z = c;}
T sum()
{ return x + y + z;}
private:
T x, y, z;
};
//使用方式,
类模板名<实际类型名>对象名;
类模板名<实际对象名>对象名(实参表列);
Three<int> sum3(3, 5, 7);
函数总览:
一、非修改序列函数
1.for_each | 将函数fn应用于 |
2.find | 在 |
3.find_if | 返回在[first,last]范围中的元素传入pred函数中返回true的第一个元素的迭代器 |
4.search | 搜索 |
5.find_end | 搜索 |
6.count | 计算[first, last)范围内等于 val 值的元素数 |
7.count_if | 在[first1,last1)范围内返回满足 pred函数条件的元素总数 |
8.search_n | 在[first, last)范围内搜索最小连续元素(count)都等于val值的第一个元素的迭代器 |
二、修改序列函数
1.copy | 复制范围内的元素 |
2.swap | 交换两个对象的值 |
3.swap_rangs | 交换两个范围的元素 |
4.reverse | 反向范围 |
5.replace | 替换范围中的元素 |
6.replace_if | 根据条件替换范围中的元素 |
7.remove | 从范围中删除元素 |
8.remove_if | 根据条件从范围中删除元素 |
9.unique | 删除范围内的连续重复项 |
三、分区
四、排序
1.sort | 排序范围内的元素 |
2.stable_sort | 将范围中的元素[first,last) 按升序排序,如sort,但stable_sort保留值相等的元素的相对顺序 |
五、二进制搜索
六、合并
七、堆
八、最大/最小
1.max | 返回两个值中的最大值(功能模板:int i , j ; max(i , j);) |
2.min | 返回两个值中的最小值 |
3.max_element | 返回范围内的最大值 |
4.min_element | 返回范围内的最小值 |
九、其他
为方便读者检索,可以点击需要查看的函数直接定位
目录
1.for_each:--> 2.find:--> 3.find_if:--> 4.search(-find_end):--> 5.find_end:--> 6.count:--> 7.count_if:--> 8.search_n:
1.copy:--> 2.swap:--> 3.swap_rangs--> 4.reverse:--> 5.replace--> 6.replace_if--> 7.remove--> 8.remove_if
函数详解:
一、非修改序列函数
1.for_each:
将函数fn应用于[first,last)
范围中的每个元素。
/*==================================================
注:fn为一元函数,该函数接受范围内的元素作为参数
InputIterator Function是参数类型,可变(数组指针,迭代器)
Function是返回类型,可变。
for_each 是函数名,不可变
使用时直接采用函数名+变量的形式进行实例化调用
==================================================*/
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function fn)
{
while (first != last)
{
fn (*first);
++first;
}
return fn; // or, since C++11: return move(fn);
}
函数用例
/*==================================================================
函数操作:for_each()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first,last).
fn-函数指针或move constructible函数对象
函数返回:返回 fn
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void myfunction(int i){
cout << ' ' << i;
}
struct myclass{
void operator()(int i){
cout << ' ' << i;
}
}myobject;
int main()
{
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains: ";
for_each(myvector.begin(), myvector.end(), myfunction); //函数名既是该函数的入口指针
cout << endl;
cout << "myvector contains: ";
for_each(myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 10 20 30
myvector contains: 10 20 30
=======================================*/
2.find:
在[first,last)
范围内比较元素值是否等于val并返回第一个等于 val元素的迭代器。如果找不到这样的元素,则该函数返回last。
template<class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
while (first != last) {
if (*first == val) return first;
++first;
}
return last;
}
函数用例
/*==================================================================
函数操作:find()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first,last).
val-要在范围内搜索的值
函数返回:比较等于 val 的范围中第一个元素的 iterator(指针类型/地址),如果没有元素匹配,则函数返回 last.
注:1.返回查找元素对应角标方法:cout << p - myints.begin();
因为find 返回值为指针类型,数组为连续存储,所以相减即可返回角标
2.find 对象为 string 类型。则返回值为 vector<char>::iterator it;类型
string str = "asfdasfs";
vector<char>::iterator it ;
it = find(helper1.begin(), helper1.end(), str[i]);
cout << helper2[it - helper1.begin()];
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
//using find with array and pointer
int myints[] = {10, 20, 30, 40};
int *p; //迭代器
p = find(myints, myints + 4, 30);
if(p != myints + 4)
cout << "Element found in myints: " << *p << endl;
else
cout << "Element not found in myints" << endl;
//using find eith vector and iterator
vector<int> myvector(myints, myints + 4);
vector<int>::iterator it;
it = find(myvector.begin(), myvector.end(), 50);
if(it != myvector.end())
cout << "Element found in myints: " << *it << endl;
else
cout << "Element not found in myints" << endl;
return 0;
}
/*=======================================
函数输出:Element found in myints: 30
Element not found in myints
=======================================*/
3.find_if:
返回在[first,last]范围中的元素传入pred函数中返回true的第一个元素的迭代器。如果没有找到这样的元素,函数返回last。
template<class InputIterator, class UnaryPredicate>
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first != last) {
if (pred(*first)) return first; //pred 一元函数指针
++first;
}
return last;
}
函数用例
/*==================================================================
函数操作:find_if()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first,last).
pred-一元函数,它接受范围内的一个元素作为参数,并返回一个可转换到bool的值。返回的值指示该元素在此函数的上下文中是否被视为匹配。
函数不能修改它的参数。
它可以是函数指针,也可以是函数对象。
函数返回:pred不返回false的范围内的第一个元素的迭代器。
如果pred对所有元素都为false,则函数返回last。
注:一元谓词(unary predicate)接受一个参数的谓词。谓词是一个可调用的表达式,其返回结果是一个能用作条件的值。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool Isodd(int i){
return ((i % 2) == 1); //判断是否是奇数
}
int main()
{
//using find with array and pointer
int myints[] = {10, 25, 30, 45};
int *p; //迭代器
p = find_if(myints, myints + 4, Isodd);
if(p != myints + 4)
cout << "The first odd value is: " << *p << endl;
else
cout << "Element not found in myints" << endl;
//using find eith vector and iterator
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
vector<int>::iterator it;
it = find_if(myvector.begin(), myvector.end(), Isodd);
if(it != myvector.end())
cout << "The fist odd value is: " << *it << endl;
else
cout << "Element not found in vector" << endl;
return 0;
}
/*=======================================
函数输出:The first odd value is: 25
Element not found in vector
=======================================*/
4.search(-find_end):
搜索[first1,last1)
定义的范围中第一次出现[first2,last2)
序列,并将迭代器返回到其第一个元素,如果没有找到,则返回last1。
equality (1) | |
---|---|
predicate (2) | |
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2 == last2) return first1; // specified in C++11
while (first1 != last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1 == *it2) { // or: while (pred(*it1,*it2)) for version 2
if (it2 == last2) return first1;
if (it1 == last1) return last1;
++it1; ++it2;
}
++first1;
}
return last1;
}
函数用例
/*==================================================================
函数操作:search()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
将迭代器转发到要搜索的序列的初始和最终位置。使用的范围是[first2,last2).
pred-二进制函数,接受两个元素作为参数(两个序列中的每一个,按相同的顺序),并返回一个可转换为的值bool。返回值指示在此函数的上下文中是否认为元素匹配。
该函数不得修改其任何参数。
这可以是函数指针或函数对象。
函数返回:一个迭代器,在[first1,last1)的范围内第一次出现[first2,last2)序列的第一个元素。
如果未找到序列,则函数返回last1。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool mypredicate(int i, int j) { return (i == j); }
int main()
{
vector<int> haystack;
//set values: haystack:10 20 30 40 50 60 70 80 90
for(int i = 1; i < 10; i++) haystack.push_back(i * 10);
//using default comparrision:
int needle1[] = {40, 50, 60, 70};
vector<int>::iterator it;
it = search(haystack.begin(), haystack.end(), needle1, needle1 + 4);
if(it != haystack.end())
cout << "needle1 found at position " << it - haystack.begin() << endl;
else
cout << "needle1 not dound" << endl;
//using predicate comparison:
int needle2[] = {20, 30, 50};
it = search(haystack.begin(), haystack.end(), needle2, needle2 + 3, mypredicate);
if(it != haystack.end())
cout << "needle1 found at position " << it - haystack.begin() << endl;
else
cout << "needle1 not dound" << endl;
return 0;
}
/*=======================================
函数输出:needle1 found at position 3
needle1 not dound
=======================================*/
5.find_end:
搜索[first1,last1)
定义的范围中最后一次出现[first2,last2)
序列,并将迭代器返回到其第一个元素,如果没有找到,则返回last1。
equality (1) | |
---|---|
predicate (2) | |
//注:forwarditerator 前向迭代器
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2 == last2) return last1; // specified in C++11
ForwardIterator1 ret = last1;
while (first1 != last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1 == *it2) { // or: while (pred(*it1, *it2)) for version (2)
++it1; ++it2;
if (it2 == last2) { ret = first1; break; }
if (it1 == last1) return ret;
}
++first1;
}
return ret;
}
函数用例
/*==================================================================
函数操作:find_end()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
[first2, last2)-待匹配序列
pred-二元函数,接受两个元素作为参数(两个序列中的每一个,按相同的顺序),并返回一个可转换为的值bool。返回值指示在此函数的上下文中是否认为元素匹配。
函数不能修改它的参数。
它可以是函数指针,也可以是函数对象。
函数返回:一个迭代器,在[first1,last1)中最后出现[first2,last2)序列的第一个元素。
如果未找到序列,则函数返回last1。
注:二元谓词(Binary Predicate)接受两个参数的谓词。谓词是一个可调用的表达式,其返回结果是一个能用作条件的值。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool myfunction(int i, int j){
return (i == j);
}
int main()
{
int myints[] = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5};
vector<int> haystack(myints, myints + 10);
int needle1[] = {1, 2, 3};
vector<int>::iterator it;
it = find_end(haystack.begin(), haystack.end(), needle1, needle1 + 3);
if(it != haystack.end())
cout << "needle1 last found at position: " << it - haystack.begin() << endl;
int needle2[] = {4, 5, 1};
it = find_end(haystack.begin(), haystack.end(), needle2, needle2 + 3, myfunction);
if(it != haystack.end())
cout << "needle1 last found at position: " << it - haystack.begin() << endl;
return 0;
}
/*=======================================
函数输出:needle1 last found at position: 5
needle1 last found at position: 3
=======================================*/
6.count:
计算[first, last)范围内等于 val 值的元素数。
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& val)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first != last) {
if (*first == val) ++ret;
++first;
}
return ret;
}
函数用例
/*==================================================================
函数操作:count()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
val-需要匹配的值
函数返回:在[first1,last1)范围内等于 val 的元素数
返回类型(iterator_traits <InputIterator> :: difference_type)是有符号整数类型。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool myfunction(int i, int j){
return (i == j);
}
int main()
{
int myints[] = {10, 20, 30, 30, 20, 10, 10, 20};
long mycount = count(myints, myints + 8, 10);
cout << "10 appears " << mycount << "times." << endl;
vector<int> myvector(myints, myints + 8);
mycount = count(myvector.begin(), myvector.end(), 20);
cout << "20 appears " << mycount << "times." << endl;
return 0;
}
/*=======================================
函数输出:10 appears 3times.
20 appears 3times.
=======================================*/
7.count_if:
在[first1,last1)范围内返回满足 pred函数条件的元素数
template <class InputIterator, class UnaryPredicate>
typename iterator_traits<InputIterator>::difference_type
count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first != last) {
if (pred(*first)) ++ret;
++first;
}
return ret;
}
函数用例
/*==================================================================
函数操作:count_if()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
pred-一元函数接受范围内的元素作为参数,并返回可转换为bool的值。若返回值为真则此元素参与计数,否则舍弃。
函数返回:在[first1,last1)范围内pred 不返回 FALSE的元素数
返回类型(iterator_traits <InputIterator> :: difference_type)是有符号整数类型。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool Isodd(int i) { return ((i % 2) == 1); }
int main()
{
vector<int> myvetor;
for(int i = 1; i < 10; i++) myvetor.push_back(i);
long mycount = count_if(myvetor.begin(), myvetor.end(), Isodd);
cout << "myvector contatins " << mycount << " odd value." <<endl;
return 0;
}
/*=======================================
函数输出:myvector contatins 5 odd value.
=======================================*/
8.search_n:
在[first, last)范围内搜索最小连续元素(count)都等于val值的第一个元素的迭代器。
equality (1) (-count) | |
---|---|
predicate (2) (-cont_if) | |
template<class ForwardIterator, class Size, class T>
ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
Size count, const T& val)
{
ForwardIterator it, limit;
Size i;
limit=first; std::advance(limit,std::distance(first,last)-count);
while (first!=limit)
{
it = first; i=0;
while (*it==val) // or: while (pred(*it,val)) for the pred version
{ ++it; if (++i==count) return first; }
++first;
}
return last;
}
函数用例
/*==================================================================
函数操作:search_n()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
将迭代器转发到要搜索的序列的初始和最终位置。使用的范围是[first2,last2).
count-要匹配的最小连续元素数(int 类型)
val-要比较的单个值,或作为 pred的参数
pred-二进制函数,接受两个元素作为参数(序列中的一个元素作为一个,val 作为第二个),并返回一个可转换为的值bool。返回值指示在此函数的上下文中是否认为元素匹配。
该函数不得修改其任何参数。
这可以是函数指针或函数对象。
函数返回:一个迭代器,匹配序列的第一个元素
如果没有找到这样的序列,则返回 last
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool mypredicate(int i, int j) { return (i == j); }
int main()
{
int myints[] = {10, 20, 30, 30, 20, 10, 10, 20};
vector<int> myvector(myints, myints + 8);
vector<int>::iterator it;
//using default comparrision:
it = search_n(myvector.begin(), myvector.end(), 2, 30);
if(it != myvector.end())
cout << "two 30s found at position " << it - myvector.begin() << endl;
else
cout << "match not dound" << endl;
//using predicate comparison:
it = search_n(myvector.begin(), myvector.end(), 2, 10, mypredicate);
if(it != myvector.end())
cout << "two 10s found at position " << it - myvector.begin() << endl;
else
cout << "match not dound" << endl;
return 0;
}
/*=======================================
函数输出:two 30s found at position 2
two 10s found at position 5
=======================================*/
二、修改序列函数
1.copy:
将[first,last)
范围中的元素复制到从result开始的范围内。
/*===================================================
注:InputIterator/OutputIterator分别是输入迭代器和输出
迭代器,可以理解为一个指针类型。
===================================================*/
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
函数用例
/*==================================================================
函数操作:copy()
函数形参:将迭代器输入到序列中的初始位置和最终位置。使用的范围是[first1,last1).
将迭代器输出到目标序列中的初始位置,但不应该是[first1,last1)范围内的任意元素
函数返回:到目标范围末尾的迭代器(指向复制的最后一个元素之后的元素),其中元素已被复制。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int myints[] = {10, 20, 30, 30, 20, 10, 10, 20};
vector<int> myvector(7); //输出容器大小应能存储全部复制数据
copy(myints, myints + 7, myvector.begin());
cout << "myvector contains: ";
for(int i = 0; i < myvector.size(); i++)
cout << myvector[i] << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 10 20 30 30 20 10 10
=======================================*/
2.swap:
交换两个对象的值
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
template <class T, size_t N> void swap (T (&a)[N], T (&b)[N])
{
for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}
函数用例:
/*==================================================================
函数操作:swap()
函数形参:两个对象,其内容被交换
函数返回:无
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool mypredicate(int i, int j) { return (i == j); }
int main()
{
int x = 10, y = 20;
swap(x, y);
vector<int> foo(4, x), bar(6, y);
swap(foo, bar);
cout << "foo contains: ";
for(vector<int>::iterator it = foo.begin(); it < foo.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:foo contains: 10 10 10 10 10 10
=======================================*/
3.swap_rangs
将[first1,last1)
范围中每个元素的值,与从first2开始的相同范围的对应位置的各个元素值进行交换。
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2)
{
while (first1!=last1) {
swap (*first1, *first2);
++first1; ++first2;
}
return first2;
}
函数用例
/*==================================================================
函数操作:swap_ranges()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
first2-将迭代器转发到要交换的其他序列中的初始位置。使用的范围包括与范围[first1,last1]相同数量的元素。
两个范围不得重叠
函数返回:在第二个序列中参与交换的最后一个元素的下一个元素的迭代器
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> myvector1;
for(int i = 1; i <= 5; i++)
myvector1.push_back(i);
vector<int> myvector2;
for(int i = 6; i <= 10; i++)
myvector2.push_back(i);
vector<int>::iterator it;
it = swap_ranges(myvector1.begin() + 1, myvector1.end() - 1, myvector2.begin());
cout << *it << endl;
// print out results of swap:
cout << "myvector1 contains:";
for (it = myvector1.begin(); it != myvector1.end(); ++it)
cout << *it << ' ';
cout << endl;
cout << "myvector2 contains:";
for (it = myvector2.begin(); it != myvector2.end(); ++it)
cout << *it << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector1 contains:1 6 7 8 5
myvector2 contains:2 3 4 9 10
=======================================*/
4.reverse:
反转[first,last)
范围中元素的顺序。
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
函数用例
/*==================================================================
函数操作:reverse()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
BidirectionalIterator 指向交换类型是否正确定义
函数返回:无
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> myvector1;
for(int i = 1; i <= 5; i++)
myvector1.push_back(i);
vector<int> myvector2;
for(int i = 6; i <= 10; i++)
myvector2.push_back(i);
reverse(myvector1.begin(), myvector1.end());
reverse(myvector2.begin() + 1, myvector2.end() - 1);
// print out results of swap:
vector<int>::iterator it;
cout << "myvector1 contains:";
for (it = myvector1.begin(); it != myvector1.end(); ++it)
cout << *it << ' ';
cout << endl;
cout << "myvector2 contains:";
for (it = myvector2.begin(); it != myvector2.end(); ++it)
cout << *it << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector1 contains:5 4 3 2 1
myvector2 contains:6 9 8 7 10
=======================================*/
5.replace
用new_value替换范围内[first,last)所有
等于old_value的元素。
template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value)
{
while (first != last) {
if (*first == old_value) *first = new_value;
++first;
}
}
函数用例
/*==================================================================
函数操作:replace()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
old_value 要替换的值
new_valye 替换的值
函数返回:无
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int myints[] = {10 ,20 ,30 ,30, 20, 10, 10, 20};
vector<int> myvector(myints, myints + 7);
replace(myvector.begin(), myvector.end(), 20, 99);
cout << "myvector contains: ";
for(vector<int>::iterator it = myvector.begin(); it < myvector.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 10 99 30 30 99 10 10
=======================================*/
6.replace_if
在[first,last)范围内的元素,通过 pred函数后返回值为 TRUE的元素,用 value 来替换。
template < class ForwardIterator, class UnaryPredicate, class T >
void replace_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred, const T& new_value)
{
while (first!=last) {
if (pred(*first)) *first=new_value;
++first;
}
}
函数用例:
/*==================================================================
函数操作:replace_if()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
pred-一元函数接受范围内的元素作为参数,并返回可转换为的值bool。返回的值表示是否要替换元素(如果true替换它)。
该函数不得修改其参数。
这可以是函数指针或函数对象。
value-要替换的值
函数返回:无
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
//using namespace std;
bool IsOdd (int i) { return ((i % 2) == 1); }
int main () {
std::vector<int> myvector;
// set some values:
for (int i = 1; i < 10; i++) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0
std::cout << "myvector contains: ";
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); it++)
std::cout << *it << ' ';
std::cout << std::endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 0 2 0 4 0 6 0 8 0
=======================================*/
7.remove
将[first,last)
范围中所有等于val的元素移除,并将迭代器返回到该范围的新结尾。
该函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):删除是通过将下一个与 val不匹配的元素 前移来替换 val元素来完成的。
保留了未删除元素的相对顺序,而返回迭代器和last之间的元素保持有效但未指定的状态。
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
return result;
}
函数用例
/*==================================================================
函数操作:remove()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
value-要删除的值
函数返回:未删除的最后一个元素后面的元素的迭代器。
first和this迭代器之间的范围包括序列中不比较等于val的所有元素。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
int myints[] = {10, 20, 30, 30, 20, 10, 10, 20};
//bounds of rang:
int* pbegin = myints;
int* pend = myints + sizeof(myints) / sizeof(int);
pend = remove(pbegin, pend, 20);
cout << "rang contains: ";
for(int* p = pbegin; p != pend; p++)
cout << *p << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:rang contains: 10 30 30 10 10
=======================================*/
8.remove_if
将[first,last)
范围中所有pred 返回 TRUE的元素移除,并将迭代器返回到该范围的新结尾
该函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):删除是通过用下一个元素替换pred返回true
的元素来完成的。
template <class ForwardIterator, class UnaryPredicate>
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred)
{
ForwardIterator result = first;
while (first!=last) {
if (!pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
函数用例
/*==================================================================
函数操作:remove_if()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
pred-一元函数接受范围内的元素作为参数,并返回可转换为的值bool。返回的值指示是否要删除元素(如果要删除true它)。
该函数不得修改其参数。
这可以是函数指针或函数对象。
函数返回:未删除的最后一个元素后面的元素的迭代器。
first和this迭代器之间的范围包括序列中不比较等于val的所有元素。
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool IsOdd (int i) { return ((i % 2) == 1); }
int main ()
{
int myints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
//bounds of rang:
int* pbegin = myints;
int* pend = myints + sizeof(myints) / sizeof(int);
pend = remove_if(pbegin, pend, IsOdd);
cout << "rang contains: ";
for(int* p = pbegin; p != pend; p++)
cout << *p << ' ';
cout << endl;
return 0;
}
/*=======================================
函数输出:rang contains: 2 4 6 8
=======================================*/
9.unique:
删除范围内的连续重复项
从[first,last)范围中的每个连续的等效元素组中删除除第一个元素之外的所有元素。
该函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):通过用下一个不重复的元素替换重复元素来完成删除,并且通过将迭代器返回到应该被视为其新的past-the-end元素来发信号通知缩短范围的新大小,即删除重复元素后最后一个元素的下一个元素位置。
保留未删除元素的相对顺序,而返回的迭代器和last之间的元素保留在有效但未指定的状态。
equality (1) | template <class ForwardIterator> ForwardIterator unique (ForwardIterator first, ForwardIterator last); |
---|---|
predicate (2) | template <class ForwardIterator, class BinaryPredicate> ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); |
template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last)
{
if (first==last) return last;
ForwardIterator result = first;
while (++first != last)
{
if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)
*(++result)=*first;
}
return ++result;
}
函数用例
// unique algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::unique, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10
std::vector<int> myvector (myints,myints+9);
// using default comparison:
std::vector<int>::iterator it;
it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ?
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10
// using predicate comparison:
std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes)
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
四、排序
1.sort:
将[first,last)
范围中的元素按升序排列
default (1) | |
---|---|
custom (2) | |
函数用例
/*==================================================================
函数操作:remove_if()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
RandomAccessIterator 是能在常数时间内移动到指向任何元素的位置
comp-二进制函数,接受范围中的两个元素作为参数,并返回可转换为的值bool。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
该函数不得修改其任何参数。
这可以是函数指针或函数对象。
函数返回:无
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
//using namespace std;
bool myfunction (int i,int j) { return (i<j); }
struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobject;
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33
// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33
// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)
// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
/*=======================================
函数输出:myvector contains: 12 26 32 33 45 53 71 80
=======================================*/
2.stable_sort:
将范围中的元素[first,last)
按升序排序,如sort,但stable_sort保留具有等效值的元素的相对顺序
template <class RandomAccessIterator>
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
函数用例
/*==================================================================
函数操作:stable_sort()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
RandomAccessIterator 是能在常数时间内移动到指向任何元素的位置
comp-二进制函数,接受范围中的两个元素作为参数,并返回可转换为的值bool。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
该函数不得修改其任何参数。
这可以是函数指针或函数对象。
函数返回:void
=================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool compare_as_ints (double i,double j)
{
return (int(i)<int(j)); //只舍不进位
}
int main ()
{
double mydoubles[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};
vector<double> myvector;
myvector.assign(mydoubles, mydoubles+8);
cout << "using default comparison:";
stable_sort (myvector.begin(), myvector.end());
for (vector<double>::iterator it = myvector.begin(); it != myvector.end(); it++)
cout << ' ' << *it;
cout << endl;
myvector.assign(mydoubles, mydoubles+8); //第一次排序后再次赋值
cout << "using 'compare_as_ints' :";
stable_sort (myvector.begin(), myvector.end(), compare_as_ints);
for (vector<double>::iterator it = myvector.begin(); it != myvector.end(); it++)
cout << ' ' << *it;
cout << '\n';
return 0;
}
/*=======================================
函数输出:using default comparison: 1.32 1.41 1.62 1.73 2.58 2.72 3.14 4.67
using 'compare_as_ints' : 1.41 1.73 1.32 1.62 2.72 2.58 3.14 4.67
=======================================*/
八、最大/最小
1.max_element / min_element
返回指向范围[first,last)
中具有最大值的元素的迭代器。
default (1) | |
---|---|
custom (2) | |
template <class ForwardIterator>
ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
if (first==last) return last;
ForwardIterator largest = first;
while (++first!=last)
if (*largest<*first) // or: if (comp(*largest,*first)) for version (2)
largest=first;
return largest;
}
函数用例
/*==================================================================
函数操作:max_element()
函数形参:将前向迭代器转发到要交换的序列之一的初始位置和最终位置。使用的范围是[first1,last1]
RandomAccessIterator 是能在常数时间内移动到指向任何元素的位置
comp-二进制函数,接受范围中的两个元素作为参数,并返回可转换为的值bool。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
该函数不得修改其任何参数。
这可以是函数指针或函数对象。
函数返回:范围中最大值的迭代器,如果范围为空,则返回 last
=================================================================*/
#include <iostream>
//#include <vector>
#include <algorithm>
//using namespace std;
bool myfn(int i, int j) { return i<j; }
struct myclass {
bool operator() (int i,int j) { return i<j; }
} myobj;
int main () {
int myints[] = {3,7,2,5,6,4,9};
// using default comparison:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n';
// using function myfn as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myfn) << '\n';
// using object myobj as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myobj) << '\n';
return 0;
}
/*=======================================
函数输出:The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
=======================================*/