#include<algorithm>

#include<algorithm>

标准库还定义了一组泛华的算术算法,命名习惯和泛型算法相同,使用这些算法必须:

#include<numeric>

 

Ø  #include<numeric>

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

    用于指定累加起始值的第三个实参是必要的,因为 accumulate 对将要累加的元素类型一无所知,因此,除此之外,没有别的办法创建合适的起始值或者关联的类型。容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。

使用 accumulate string 型的 vector容器中的元素连接起来:

string sum = accumulate(v.begin(), v.end(), string(""));

如果传递一个字符串字面值,将会导致编译时错误。因为此时,累加和的类型将是 const char*,而 string的加法操作符所使用的操作数则分别是 string const char* 类型,加法的结果将产生一个 string对象,而不是 const char* 指针。

 

Ø  fill(vec.begin(), vec.end(), 0)

    fill_n(vec.begin(), 10, 0)

对指定数目的元素做写入运算,或者写到目标迭代器的算法,都不检查目标的大小是否足以存储要写入的元素。所以一定要注意!

 

Ø   back_inserter

确保算法有足够的元素存储输出数据的一种方法是使用插入迭代器。插入迭代器是可以给基础容器添加元素的迭代器。通常,用迭代器给容器元素赋值时,被赋值的是迭代器所指向的元素。而使用插入迭代器赋值时,则会在容器中添加一个新元素,其值等于赋值运算的右操作数的值。

back_inserter函数是迭代器适配器。与容器适配器一样,迭代器适配器使用一个对象作为实参,并生成一个适应其实参行为的新对象。在本例中,传递给 back_inserter的实参是一个容器的引用。back_inserter 生成一个绑定在该容器上的插入迭代器。在试图通过这个迭代器给元素赋值时,赋值运算将调用 push_back在容器中添加一个具有指定值的元素。

vector<int> vec; // empty vector

// ok: back_inserter creates an insert iterator that adds elements to vec

fill_n (back_inserter(vec), 10, 0);// appends 10 elements to vec

 

Ø  replace(vec.begin(), vec.end(), 0, 42)

如果不想改变原来的序列,则用replace_copy

replace_copy(vec.begin(), vec.end(), back_inserter(ilst), 0, 42)

则把vec的内容替换并复制到了ilst中。

 

Ø  例子:假设我们要分析一组儿童故事中所使用的单词。例如,可能想知道它们使用了多少个由六个或以上字母组成的单词。每个单词只统计一次,不考虑它出现的次数,也不考虑它是否在多个故事中出现。要求以长度的大小输出这些单词,对于同样长的单词,则以字典顺序输出。

 

为了解此问题,要做下面几项操作:

1. 去掉所有重复的单词。

2. 按单词的长度排序。

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

 

假设存到了vector<string> words

sort(words.begin(), words.end());

vector<string>::iterator end_unique =unique(words.begin(), words.end());

words.erase(end_unique, words.end());

unique的使用

  单词按次序排列后,现在的问题是:让故事中所用到的每个单词都只保留一个副本。unique算法很适合用于解决这个问题,它带有两个指定元素范围的迭代器参数。该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器,表示无重复的值范围的结束。调用 unique“删除”了相邻的重复值。给“删除”加上引号是因为 unique 实际上并没有删除任何元素,而是将无重复的元素复制到序列的前端,从而覆盖相邻的重复元素unique返回的迭代器指向超出无重复的元素范围末端的下一位置。

 

fox jumps over quick red red slow the the turtle

 

变为

 

v  下一个子问题统计长度不小于 6 的单词个数。为了解决这个问题,需要用到另外两个泛型算法:stable_sort count_if。使用这些算法,还需要一个配套的实用函数,称为谓词。谓词是做某些检测的函数,返回用于条件判断的类型,指出条件是否成立。

 

bool isShorter(const string &s1, const string &s2)

{

return s1.size() < s2.size();

}

 

bool GT6(const string &s)

{

return s.size() >= 6;

}

 

除了 sort之外,标准库还定义了 stable_sort 算法,stable_sort保留相等元素的原始相对位置。sort stable_sort都是重载函数。其中一个版本使用元素类型提供的小于(<)操作符实现比较。在查找重复元素之前,我们就是用这个 sort版本对元素排序。第二个重载版本带有第三个形参:比较元素所使用的谓词函数的名字。这个谓词函数必须接受两个实参,实参的类型必须与元素类型相同,并返回一个可用作条件检测的值。

 

stable_sort(words.begin(), words.end(), isShorter);

 

vector<string>::size_type wc = count_if(words.begin(), words.end(), GT6);

 

整个代码如下:

#include<iostream>

#include<vector>

#include<string>

#include<algorithm>

using namespace std;

 

string make_plural(int wc,const string &word, const string &ending){

       return (wc==1)?word:word+ending;

}

bool isShorter(const string &s1,const string &s2)

{

return s1.size() < s2.size();

}

bool GT6(const string &s)

{

return s.size() >= 6;

}

int main()

{

vector<string> words;

string next_word;

while (cin >> next_word) {

words.push_back(next_word);

}

sort (words.begin(), words.end());

vector<string>::iterator end_unique = unique(words.begin(), words.end());

words.erase(end_unique, words.end());

stable_sort(words.begin(), words.end(), isShorter);

vector<string>::size_type wc = count_if (words.begin(), words.end(), GT6);

cout << wc << " " <<make_plural(wc, "word", "s")<< " 6 characters or longer" << endl;

vector<string>::iterator iter=words.begin();

for(; iter!=words.end(); ++iter){

cout<<*iter<<endl;

}

return 0;

}

 

Ø  算法命名规范

查找某个值的算法通常提供第二个版本,用于查找使谓词函数返回非零值的元素。对于这种算法,第二个版本的函数名字以_if 后缀标识。类似地,很多算法提供所谓的复制版本,将(修改过的)元素写到输出序列,而不是写回输入范围。这种版本的名字以_copy 结束

 

Ø  算法从不改变序列的大小

算法从不直接改变它所操纵的序列的大小。(如果算法的实参是插入迭代器,则该迭代器会添加新元素,但算法并不直接这么做。)算法可以从一个位置将元素复制到另一个位置,但不直接添加或删除元素。

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值