zoukankan      html  css  js  c++  java
  • C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法

    STL实践与分析

    --容器特有的算法



        与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作。当中非常大的一个原因就是list容器不是依照内存中的顺序进行布局的不支持随即訪问,这样,在list容器上就不能使用随即訪问迭代器的算法,如sort等;还有其它的一些算法如:mergeremovereverseunique,尽管能够用在list上,但却付出了高昂的性能代价。因此标准库结合list的内部结构,编写出了更快算法:

    list容器特有的操作

    lst.merge(lst2)

    lst.merge(lst2,comp)

    lst2的元素合并到lst中。这两个list容器对象都必须排序。lst2中的元素将被删除合并后,lst2为空。返回void类型。第一个版本号使用<操作符,而第二个版本号则使用comp指定的比較运算

    lst.remove(val)

    lst.remove(unaryPred)

    调用lst.erase删除全部等于指定值或指定的谓词函数返回非零值的元素。返回void类型。

    lst.reverse()

    反向排列lst中的元素

    lst.sort()

    lst中的元素排序

    lst.splice(iter,lst2)

    lst.splice(iter,lst2,iter2)

    lst.splice(iter,beg,end)

    lst2的元素移到lst中迭代器iter指向的元素前面

    lst2中删除移出的元素

    第一个版本号将lst2的全部元素移到lst;合并后,lst2为空。lstlst2不能是同一个list对象。

    第二个版本号仅仅移动iter2所指向的元素,这个元素必须是lst2中的元素。在这样的情况中,lstlst2能够是同一个list对象。也就是说,可在一个list对象中使用splice运算移动一个元素。

    第三个版本号移动迭代器 begend标记的范围内的元素begend照例必须指定一个有效的范围。这两个迭代器可标记随意list对象内的范围,包含lst。当它们指定lst的一段范围时,假设iter也指向这个范围的一个元素,则该运算没有定义。

    lst.unique()

    lst.unique(binaryPred)

    调用erase删除同一个值的连续副本。第一个版本号使用

    ==操作符推断元素是否相等;第二个版本号则使用指定的谓词函数实现推断


    【最佳实践】

        对于list对象,应该优先使用list容器特有的成员版本号,而不是泛型算法


    list容器特有的算法与其泛型算法版本号之间的两个至关重要的区别。

        1)removeuniquelist本改动了其关联的基础容器:真正删除了指定的元素。比如,list::uniquelist中第二个和兴许反复的元素踢出了该容器。

    与相应的泛型算法不同list容器特有的操作能加入和删除元素

        2)list容器提供的mergesplice运算会破坏它们的实參。使用 merge的泛型算法版本号时,合并的序列将写入目标迭代器指向的对象,而它的两个输入序列保持不变。可是,使用list容器的 merge成员函数时,则会破坏它的实參list对象 –当实參对象的元素合并到调用 merge函数的list对象时,实參对象的元素被移出并删除。

    //P362 习题11.29
    bool GT4(const string &str)
    {
        return str.size() >= 4;
    }
    
    bool compLength(const string &s1,const string &s2)
    {
        return s1.size() < s2.size();
    }
    
    int main()
    {
        list<string> words;
        ifstream inFile("input");
    
        string str;
        while (inFile >> str)
        {
            words.push_back(str);
        }
    
        words.sort();
        words.unique();
    
        list<string>::size_type word_cnt = count_if(words.begin(),words.end(),GT4);
    
        cout << "Have " << word_cnt << " words more the 4 characters." << endl;
    
        words.sort(compLength);
    
        for (list<string>::iterator iter = words.begin(); iter != words.end(); ++iter)
        {
            cout << *iter << endl;
        }
    }
    

    //演示样例程序:并不实现什么功能,仅仅做演示之用
    #include <iostream>
    #include <list>
    #include <fstream>
    using namespace std;
    
    bool comp(int a,int b)
    {
        return a > b;
    }
    
    void printList(const list<int> &iList)
    {
        for (list<int>::const_iterator iter = iList.begin(); iter != iList.end(); ++iter)
        {
            cout << *iter << '	';
        }
        cout << endl;
    }
    
    list<int> iList1,iList2;
    
    void printAll()
    {
        cout << "iList1: " << endl;
        printList(iList1);
        cout << "iList2: " << endl;
        printList(iList2);
    }
    
    void initList(list<int> &iList)
    {
        for (list<int>::size_type i = 0; i != 20; ++i)
        {
            iList.push_back(i);
        }
    }
    
    int main()
    {
    
        for (list<int>::size_type i = 0; i != 20; ++i)
        {
            iList1.push_back(i);
            iList2.push_back(i + 10);
        }
        printAll();
    
        iList1.merge(iList2,comp);
        printAll();
    
        iList1.sort();
        initList(iList2);
        printAll();
    
        iList1.unique();
        cout << "iList1" << endl;
        printList(iList1);
    }

  • 相关阅读:
    es6箭头函数
    es6数组必看太实用了
    对象和数组的解构以及数组的遍历4种写法
    es6 map数据类型,要比set还很多
    es6中对象的一些操坐
    class类
    webStorm配置es6转es5
    gulp-babel,es6转es5
    jquery扩展插件,让demo元素也可以resize
    【leetcode刷题笔记】Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3770695.html
Copyright © 2011-2022 走看看