泛型算法参考手册
算法参考的对象序列如下:
int ia[8] = {1,3,6,10,15,21,28,36};//sum = 120
vector<int> ivec(ia, ia+8);
list<int> ilist(ia, ia+8);
string sa[10] =
{
"The", "light", "untonsured",
"hair", "grained", "and",
"hued", "like", "pale",
"oak"
};
vector<string> svec(sa, sa+10);
list<string> slist(sa, sa+10);
accumulate() 元素累加
#include <numeric>
int iresult = accumulate(ia, ia+8, 10);
结果 iresult = 130
也可以传入一个二元运算,如下
int iresult2 = accumulate(ia, ia+8, 100, plus<int>());
adjacent_difference() 相邻元素的差额
#include <numeric>
产生一个新数列,除了第一个元素,每个元素都是原来数列的“相同位置”及前一位置的差。
假设数列为{1,2,3,5,4},那么新的数列是{1,1,1,2,-1}。第三个参数用来存放结果。
adjacent_difference(ilist.begin(), ilist.end(), iresult.begin());
也可以传入一个二元元素,取代默认的“相减”操作:
adjacent_difference(ilist.begin(), ilist.end(), iresult.begin(), multiplies<int());
adjacent_find() 搜索相邻的重复元素
#include <algorithm>
class TwiceOver
{
public:
bool operator()(int val1, int val2)
{return val1 == val2/2 ? true : false;}
};
//搜索第一组“相邻且值重复“的元素,如数列为{1,3,5,5,6},返回5;
int *piter = adjacent_find(ia, ia+8);
// 返回一个iterator
iter = adjacent_find(vec.begin(), vec.end(), TwiceOver()};
binary_search() 二元搜索
该查询假设处理对象以 less-than 运算符排序,如果该容器以其他方式完成排序,那么调用时需要传入该二元原算符。返回true or false
#include <algorithm>
bool found_it = binary_search(ilist.begin(), ilist.end(), 1);
bool found_it = binary_search(ilist.begin(), ilist.end(), 1, greater<int>());
copy() 复制
#include <algorithm>
ostream_iterator<int> ofile(cout, " ");
copy(vec.begin(), vec.end(), ofile);
vector<string> target(svec.size());
copy (svec.begin(), svec.end(), target.begin());
copy_backward() 逆向复制
和copy几乎一样,复制操作逆向行之。
#include <algorithm>
copy (svec.begin(), svec.end(), target.begin());
count() 计数
返回容器中与制定值相等的元素个数
#include <algorithm>
count(svec.begin(), svec.end(), "abc");
count_if() 在特定条件下计数
返回容器中与制定值相等的元素个数
#include <algorithm>
class Even
{
public:
bool operator()(int val)
{return val==6;}//返回等于6的个数
};
int count = count_if(ilist.begin(), ilist.end(), Even());
cout << count;
若 ilist = 3,6,6,8,7则结果为2
equal() 是否相等
若两数列值都相同返回 true,如果第二个数列值较多,多出来的不予考虑,也可以传入一个二元function object 或者 function pointer。
#include <algorithm>
class EqualAndOdd
{
public:
bool operator()(int val1, int val2)
{return val1 != val2;}//返回不等于的状况
};
int ia1[] = {1,2,3,4};
int ia2[] = {1,2,3,4,5,6};
int ia3[] = {0,0,0,0};
bool count1 = equal(ia1, ia1+4, ia2);//true
bool count2 = equal(ia1, ia1+4, ia3, EqualAndOdd());//true
fill() 改填元素值
将容器内每个元素设置为某特定值
#include <algorithm>
fill(ivec.begin(), ivec.end(), value);
fill_n() 改填元素值
将容器内元素设定为某特定值,只设定n个元素
#include <algorithm>
fill_n(ia, count, value);
fill_n(svec.begin(), count, string_value);
find() 搜寻
和特定值比较,找到就结束,返回一个iterator指向该元素,没有找到,返回end().
#include <algorithm>
fill(ivec.begin(), ivec.end(), value);
*p = find(ia, ia+8, 6);
iter = find(svec.begin(), svec.end(), "abc");
find_end() 查找某个子序列最后一次出现的地方
也可以指定一个二元运算
#include <algorithm>
int ia1[] = {1,2,3,4,1,2,3,5,7};
int ia2[] = {1,2,3};
//found_it 指向ia1[4]
found_it = find_end(ia1, ia1 + 9, ia2, ia2+3);
find_first_of() 查找某个子序列第一次出现的地方
也可以指定一个二元运算
#include <algorithm>
int ia1[] = {1,2,3,4,1,2,3,5,7};
int ia2[] = {1,2,3};
//found_it 指向ia1[0]
found_it = find_end(ia1, ia1 + 9, ia2, ia2+3);
find_if() 在特定条件下查找
会被施以一个二元运算
#include <algorithm>
found_it = find_end(vec.begin(), vec.end(), LessThanVal(ival));
for_each() 对范围内的元素施行某个操作
#include <algorithm>
template <typename T>
void print_elem(T elem){cout << elem << " ";}
for_each(ivec.begin(), ivec.end(), print_elem);
generate() 以指定操作的运算结果填充特定范围的元素
#include <algorithm>
class GenByTwo{
public:
void operator()(){
static int seed = -1; return seed+=2;}
};
list<int ilist(5);
//填入ilist的内容为: 1 , 3, 5, 7, 9
generate(ilist.begin(), ilist.end(), GenByTwo());
generate_n() 以指定操作的运算结果填充n个元素
generate_n() 会连续调用指定操作n次, 将n次结果填入序列的n个元素
#include <algorithm>
class GenByTwo{
public:
GenByTwo( int seed =0) :_seed(seed){}
int operator()(){return _seed+=2;}
private:
int _seed;
};
vector<int> ivec(10);
//填入ilist的内容为: 52 , 54, 56, 58, 60
generate(ilist.begin(), ilist.end(), GenByTwo(50));
includes() 涵盖于
如果第二序列内元素都在第一序列中,返回true, 否则返回false,两个序列都必须经过排序, 排序方式可以通过 less-than 运算符(默认), 或者由第四个参数指定。
#include <algorithm>
int ia1[] = {1,2,3,4,1,2,3,5,7};
int ia2[] = {3,1,2};
//必须排序
sort(ia1, ia1 + 9);
sort(ia2, ia2+3);
res = includes(ia1, ia1+9, ia2, ia2+3)//true
inner_product() 内积
会将两个序列值彼此相乘, 并累加,然后加上某个初始值。
如, {2, 3, 5, 8} 和 {1, 2, 3, 4}, 处理就是: (2*1) + (3*2) + (5*3) + (8*4), 然后加上初始值。
#include <numeric>
int ia1[] = {2, 3, 5, 8};
int ia2[] = {1, 2, 3, 4};
int res = inner_product(ia1, ia2 + 4, ia2, 5);
vector<int> vec1(ia1, ia1 + 4);
vector<int> vec2(ia2, ia2 + 4);
res = inner_roduct(vec1.begin(), vec1.end(), vec2.begin(), 0, minus<int>(), plus<int>());
inplace_merge() 合并并取代(改写)
inplace_merge() 接收3个iterators: first, middle, last, 连个序列必须连续。
也可传入第4个参数,指定 less-than(默认) 运算符以外的操作
#include <numeric>
int ia[8] = {3, 2, 8, 5, 7, 6, 4, 9};
int *middle = ia+4;
int *last = ia +8;
// 2, 3, 5, 8 //4, 6, 7, 9
sort(ia, middle); sort(middle, last);
// 2,3,4,5,6,7,8,9
inplace_merge(ia, middle, last);
iter_swap() 元素互换
将两个iterators 所指向的元素值互换
#include <numeric>
typedef list<int>::iterator iterator;
iterator it1 = list.begin(), it2 = list.begin() +4;
iter_swap(it1, it2);
lexicographical_compare() 以字典排列方式做比较
也可传入第5个参数,指定 less-than(默认) 运算符以外的操作,如果第一序列小于第二序列,返回true.
#include <algorithm>
class size_compare{
public:
bool operator() { const string &a, const string &b){
return a.length() <= b.length();
}
};
string sa1[] = { "piglet", "pooh", "tigger"};
string sa2[] = { "piglet", "pooch", "evyore"};
//false: 'c' < 'h'
res = lexicographical_compare(sa1, sa1+3, sa2, sa2+3);
list<string> ilist1(sa1, sa1+3);
list<string> ilist2(sa2, sa2+3);
//true: pooh < pooch
res = lexicographical_compare(ilist1.begin(), ilist1.end(),
ilist2.begin(), ilist2.end(), size_compare());
max(), min() 最大值/最小值
返回两元素中的最大或者最小值
max_element(), min_e.ement() 最大值/最小值 所在位置
返回一个 iterator, 指向系列中最大(小)元素,如果提供第三参数,可以设定不同比较方式。
#include <algorithm>
vector<int>::const_iterator iter:
iter = max_emement(ivec.begin(), ivec.end());
iter = min_emement(ivec.begin(), ivec.end());
merge() 合并两个序列