c++11の泛型算法

一、泛型算法泛型算法这个概念是针对容器操作的,我们知道,c++11的顺序容器有vector,list,deque等,对于这些容器,c++11并没给出相应的增删改查方法,而是定义了一组泛型算法

一般的泛型算法都定义在#include <algorithm>中,对于数值的有些算法则定义在#include <numeric>中

1、find

vector<int>::const_iterator result =  find(vec.begin(), vec.end(), search_value)

找到就返回指向该元素的迭代器,没找到就返回第二个迭代器实参

    vector<string> vec_test = { "I","love","c++" ,"and","I","know","how","to","user","it"};
vector<string>::iterator it = find(vec_test.begin(), vec_test.end(), "it"); //最后一个值可以是lambda表达式,精确筛选
cout<<*it<< endl;

由于 find 运算是基于迭代器的,因此可在任意容器中使用相同的 find 函数查找值。

类似地,由于指针的行为与作用在内置数组上的迭代器一样,因此也可以使用 find 来搜索数组:int ia[6] = {27, 210, 12, 47, 109, 83};

int *result = find(ia, ia + 6, 12);

2、accumulate

该算法在 numeric 头文件中定义。假设 vec 是一个 int 型的 vector 对象,下面的代码:

int sum = accumulate(vec.begin(), vec.end(), 42);

将 sum 设置为 vec 的元素之和再加上 42。第三个形参则是累加的初值。

用于指定累加起始值的第三个实参是必要的,因为 accumulate 对将要累加的元素类型一无所知

这个事实有两层含义。首先,调用该函数时必须传递一个起始值,否则,accumulate 将不知道使用什么起始值。其次,容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。

    vector<int> vec_test = {,,,,,,,,,,,};
int sum = accumulate(vec_test.cbegin(),vec_test.cend(),);
cout << sum;

3、find_first_of

这个算法带有两对迭代器参数来标记两段元素范围,在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到元素,则返回第一个范围的 end 迭代器。

    vector<string> vec_1{"what", "did", "i", "do"};
vector<string> vec_2{ "no", "did", "you", "do" };
vector<string>::const_iterator it = find_first_of(vec_1.cbegin(), vec_1.cend(), vec_2.cbegin(),vec_2.cend());
cout << *it << endl;

4、fill

    vector<int> vec_test = {,,,,,,,};
fill(vec_test.begin(), vec_test.end(), );
vector<int>::iterator it = vec_test.begin();
while (it!= vec_test.end())
{
cout << *it << endl;
it++;
}

5、fill _n

带有的参数包括:一个迭代器、一个计数器以及一个值。该函数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。fill_n 函数假定对指定数量的元素做写操作是安全的。

初学者常犯的错误的是:在没有元素的空容器上调用 fill_n 函数(或者类似的写元素算法)。

    it = vec_test.begin();
fill_n(vec_test.begin(), ,);
while (it != vec_test.end())
{
cout << *it << endl;
it++;
}

6、back_inserter

这个函数是迭代器适配器,插入迭代器可以给基础容器添加元素的迭代器

使用 back_inserter 可以生成一个指向 fill_n 写入目标的迭代器:

    vector<int> vec;                      // empty
fill_n(back_inserter(vec), , );
auto it = vec.begin();
while (it != vec.end())
{
cout << *it << endl;
it++;
}

7、copy

    list<int> ilst = { ,,,,,,,,,,,, };
vector<int> ivec; // empty
copy(ilst.begin(), ilst.end(), back_inserter(ivec));
auto it = ivec.begin();
while (it != ivec.end())
{
cout << *it << endl;
it++;
}

8、replace

这个算法接受第三个迭代器实参,指定保存调整后序列的目标位置。

如果不想改变原来序列,调用replace_copy()

调用该函数后,ilst 没有改变,ivec 存储 ilst 一份副本,而 ilst 内所有的 0 在 ivec 中都变成了 42。

    list<int> ilst = { ,,,, };
replace(ilst.begin(), ilst.end(), , );
auto it = ilst.begin();
while (it != ilst.end())
{
cout << *it << endl;
it++;
} list<int> ilst = { ,,,, };
vector<int> vec;
replace_copy(ilst.begin(), ilst.end(),back_inserter(vec),, );
auto it = ilst.begin();
while (it != ilst.end())
{
cout << *it << endl;
it++;
}
auto it2 = vec.begin();
while (it2 != vec.end())
{
cout << *it2 << endl;
it2++;
}

9、

对容器元素重新排序的算法

按单词长度排序  sort排序

去掉所有重复单词  调用 unique“删除”了相邻的重复值。给“删除”加上引号是因为 unique 实际上并没有删除任何元素,而是将无重复的元素复制到序列的前端,从而覆盖相邻的重复元素。unique 返回的迭代器指向超出无重复的元素范围末端的下一位置。然后用erase

统计长度等于或超过6个字符的单词个数 

    auto GT6 = [](const string &s) -> bool { return s.size() >= ; };

    vector<string> vec = { "ok","work","over","handsome","red","red","slow","a","the","turtle" };
sort(vec.begin(), vec.end()); //排序
vector<string>::iterator it = unique(vec.begin(), vec.end()); //移动重复元素,返回不重复的下一个位置的迭代器
vec.erase(it, vec.end()); //删除重复元素
vector<string>::iterator it1 = vec.begin();
int n = ;
while (it1 != vec.end())
{
if (GT6(*it1))
n++;
cout << *it1++ << " ";
}
cout << endl << "the words size no less than 5 have :" << n << endl;
上一篇:js进制转换


下一篇:PAT (Advanced Level) 1059. Prime Factors (25)