c++学习记录8(GeekBand)

这周的课讲了将泛型算法。现在将泛型算法收集下,备用。

(1)泛型算法用迭代器来解决第一个要求:遍历容器。所有迭代器都支持自增操作符,从一个元素定位下一个元素,并提供解引用操作符访问元素的值 

(2)算法也许会改变存储在容器中的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删除元素。  

【 只读算法】 

 (3)只读算法是 accumulate,该算法在 numeric 头文件中定义。  accumulate 带有三个形参。头两个形参指定要累加的元素范围。第三个形参则是累加的初值。 假设 vec 是一个 int 型的 vector 对象,下面的代码:      

// sum the elements in vec starting the summation with the value 42      

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

 将 sum 设置为 vec 的元素之和再加上 42。 首先,调用该函数时必须传递一个起始值,否则,accumulate 将不知道使用什么起始值。 其次,容器内的Section 11.2.  A First Look at the Algorithms元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。 

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

size_t cnt = 0;     

 list::iterator it = roster1.begin();     

 // look in roster1 for any name also in roster2      

while ((it = find_first_of(it, roster1.end(),roster2.begin(), roster2.end()))!= roster1.end())            {        

        ++cnt;        

 // we got  a match, increment it to look in the rest of roster1

        ++it;

      }

      cout << "Found " << cnt<< " names on both rosters" << endl;

    注意:find_first_of,带有两对迭代器参数。每对迭代器中,两个实参的类型必须精确匹配,但不要求两对之间的类型匹配。特别是,元素可存储在不同类型序列中,只要这两序列的元素可以比较即可。 

 【 写容器元素的算法】********************************************************** 

 (5) fill 函数,写入到输入序列的算法    fill 带有一对迭代器形参,用于指定要写入的范围,而所写的值是它的第三个形参的副本。执行时,将该范围内的每个元素都设为给定的值。如果输入范围有效,则可安全写 入。这个算法只会对输入范围内已存在的元素进行写入操作。

     fill(vec.begin(), vec.end(), 0); // reset each element  to 0      

// set  subsequence of the range to 10

      fill(vec.begin(), vec.begin() + vec.size()/2, 10); 

(6) fill_n函数,不检查写入操作的算法    fill_n 函数带有的参数包括:一个迭代器、一个计数器以及一个值。该函数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。fill_n 函数假定对指定数量的元 素做写操作是安全的。    注意:初学者常犯的错误的是:在没有元素的空容器上调用 fill_n 函数(或者类似的写元素算法):      

*****************************************************

      vectorvec; // empty vector

      // disaster: attempts to write to 10 (nonexistent) elements in vec

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

      //vec 是空的,其结果未定义,很可能导致严重的运行时错误。      *****************************************************

 (7) copy 函数,写入到目标迭代器的算法    copy 带有三个迭代器参数:头两个指定输入范围,第三个则指向目标序列的一个元素。传递给 copy 的目标序列必须至少要与输入范围一样大。    假设 ilst 是一个存放 int 型数据的 list 对象,可如下将它 copy 给一个 vector 对象:

    vectorivec; // empty vector

    // copy elements from ilst into ivec

    copy (ilst.begin(), ilst.end(), back_inserter(ivec));

 (8)算法的 _copy 版本  有些算法提供所谓的“复制(copying)”版本。这些算法对输入序列的元素做出处理,但不修改原来的元素,而是创建一个新序列存储元素的处理结果。但不修改原来的元素, 而是创建一个新序列存储元素的处理结果。

 (9)replace 算法,对输入序列做读写操作,将序列中特定的值替换为新的值  该算法带有四个形参:一对指定输入范围的迭代器和两个值。每一个等于 第一值的元素替换成第二个值。

      // replace any element  with value of 0 by 42

      replace(ilst.begin(), ilst.end(), 0, 42); 

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

      // create empty vector to hold the replacement      vector<i>ivec;

      // use back_inserter to grow destination as needed

      replace_copy (ilst.begin(), ilst.end(),back_inserter(ivec), 0, 42);

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

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

 (11)sort 算法    sort 算法带有两个迭代器实参,指出要排序的元素范围。这个算法使用小于(<)操作符比较元素。

 (12)unique 算法,该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器,表示无重复的值范围的结束。    它带有两个指定元素范围的迭代器参数。    注:调用 unique“删除”了相邻的重复值。给“删除”加上引号是因为 unique 实际上并没有删除任何元素,而是将无重复的元素复制到序列的前端,从而覆盖相邻的重复元素。unique 返回的迭代器指向超出无重复的元素范围末端的下一位置。(想真正删除元素要与erase函数连用)

 (13)stable_sort 算法,有着相同长度的元素还能以字典次序的不同而区分    stable_sort 算法有第三个形参:比较元素所使用的谓词函数的名字。这个谓词函数必须接受两个实参,实参的类型必须与元素类型相同,并返回一个可用作条件检测的值。

      // sort words by size,  but  maintain alphabetic order for words of the same size      stable_sort(words.begin(), words.end(), isShorter); 

     // comparison function to be used to sort  by word length

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

      {

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

      }

 (14)count_if 算法,统计个数    执行 count_if 时,首先读取它的头两个实参所标记的范围内的元素。每读出一个元素,就将它传递给第三个实参表示的谓词函数。此谓词函数。此谓词函数需要单个元素类型 的实参,并返回一个可用作条件检测的值。count_if 算法返回使谓词函数返回条件成立的元素个数。      vector::size_type wc =count_if(words.begin(), words.end(), GT6);

      // determine whether a length of a given word is 6 or more

      bool GT6(const string &s)

      { 

         return s.size() >= 6;

      }

  【 再谈迭代器】**************************************************************** 

 (15)插入迭代器(insert iterators):这类迭代器与容器绑定在一起,实现在容器中插入元素的功能。  插入器是一种迭代器适配器,带有一个容器参数,并生成一个迭代器,用于在指定容器中插入元素。通过插入迭代器赋值时,迭代器将会插入一个新的元素。C++ 语言提供了三种插入器,其差别在于插入元素的位置不同:

 (a)back_inserter,创建使用 push_back 实现插入的迭代器。

 (b)front_inserter,使用 push_front 实现插入。

  (c)inserter,使用 insert 实现插入操作。除了所关联的容器外,inserter 还带有第二实参:

      指向插入起始位置的迭代器。

 注:front_inserter 需要使用 push_front,只有当容器提供 push_front 操作时,才能使用 front_inserter。在 vector 或其他没有 push_front 运算的容器上使用front_inserter,将产生错下载文档到电脑,查找使用更方便1下载券  131人已下载下载还剩2页未读,继续阅读误。

      listilst, ilst2, ilst3;

    // empty lists

      // after this loop ilst contains: 3 2 1 0

      for (list::size_type i = 0; i != 4; ++i)

          ilst.push_front(i);

      // after copy ilst2 contains: 0 1 2 3

      copy (ilst.begin(), ilst.end(), front_inserter(ilst2)); 

     // after copy, ilst3 contains: 3 2 1 0

      copy (ilst.begin(), ilst.end(),

      inserter (ilst3, ilst3.begin()));

 在复制并创建 ilst2 的过程中,元素总是在这个 list 对象的所有元素之前插入。而在复制创建 ilst3 的过程中,元素则在 ilst3 中的固定位置插入。刚开始时,这个插入 位置是此 list 对象的头部,但插入一个元素后,就不再是首元素了。

  (16) iostream 迭代器

    【注】流迭代器都是类模板:任何已定义输入操作符(>> 操作符)的类型都可以定义 istream_iterator。类似地,任何已定义输出操作符(<< 操作符)的类型也可定义ostream_iterator。

      istream_iteratorcin_it(cin);    // reads ints1 from cin

      istream_iteratorend_of_stream;  // end iterator value

      // writes Sales_items from the ofstream named outfile

      // each element  is followed by a space      ofstream outfile; 

在创建 istream_iterator 时,可直接将它绑定到一个流上。另一种方法是在创建时不提供实参,则该迭代器指向超出末端位置。ostream_iterator 不提供超出末端迭代器。 在创建 ostream_iterator 对象时,可提供第二个(可选的)实参,指定将元素写入输出流时使用的分隔符。分隔符必须是 C 风格字符串。因为它是 C 风格字符串,所以必须以空字符结束;否则,其行为将是未定义的。

    【注】流迭代器的限制:

 (a)不可能从 ostream_iterator 对象读入,也不可能写到 istream_iterator 对象中。

 (b)一旦给 ostream_iterator 对象赋了一个值,写入就提交了。赋值后,没有办法再改变这个值。此外,ostream_iterator 对象中每个不同的值都只能正好输出一次。

 (c)ostream_iterator 没有 -> 操作符。

      istream_iteratorcin_it(cin);    // reads ints from cin

      istream_iteratorend_of_stream;  // end iterator value

      // initialize vec from the standard input:

      vectorvec(cin_it, end_of_stream);

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

      // writes ints to cout using " " as the delimiter

      ostream_iterator<int>output(cout, " ");

// write only the unique elements in vec to the standard output

     unique_copy(vec.begin(), vec.end(), output);

输入是: 23 109 45 89 6 34 12 90 34 23 56 23 8 89 23 输出是: 6 8 12 23 34 45 56 89 90 109

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容