zoukankan      html  css  js  c++  java
  • [C++] STL标准模板库

    STL提供了一组模板,主要包括:

    • 容器
    • 迭代器
    • 函数对象
    • 算法

    STL容器用于存储相同类型的数据,算法是完成特定任务的方法,迭代器是用来遍历容器的对象,函数对象可以是类对象或函数指针,STL为各种容器的构造和执行各种操作提供了机制。STL和面向对象思想不相关,是一种泛型编程思想。

    1.STL容器

    STL容器提供了下面几种数据结构,可以方便的调用它们处理数据。

    • string
    • vector
    • map
    • list
    • set

    vector

    vector即矢量,存储了支持随机访问的数据,可以通过重载的下标运算符[]直接读取第8个元素,不必从头遍历前7个元素。

    实例1:vector的输入输出及随机访问

    #include <iostream>
    #include <vector>
    
    using namespace std;
    const int NUM = 5;
    
    int main()
    {
        vector<int> ratings(NUM);
    
        int i;
        for(i=0; i<NUM; i++)
            cin>>ratings[i];
    
        for(i=0; i<NUM; i++)
            cout<<ratings[i]<<"
    ";
    
       cout<<"4th: "<<ratings[3]<<endl;
    return 0; }

     对vector的主要操作包括:

    size():获取容器内元素总数

    swap():交换两个容器的内容

    begin():返回容器的首个元素的迭代器

    end():返回指向容器末尾元素下一位置的迭代器

    push_back():将元素添加到容器的尾部

    erase():删除区间内元素,STL的区间表示都包括前不包括后,即后一个迭代器本身不被处理

    实例2:vector添加及删除元素

    vector<double> test;
    double temp;
    while(cin >> temp && temp >=0)
    {
        test.push_back(temp);
    }
    test.erase(test.begin(), test.begin() + 10); //如果容器的元素总数不足10个,则会发生地址错误
    cout<<"you entered "<<test.size()<<" elements.
    ";//这时的元素总数在上一步被减去了10个

    insert():第一形参表示插入的位置,后两个迭代器表示待处理的元素区间

    此外,对于数组通常需要的操作:搜索、排序、随机排序,vector的处理方式是不提供类方法,而是提供非成员函数,这样可尽量减小类的体积,省去大量重复的工作。

    实例3:定义并使用非成员函数(包括重载运算符)

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    struct Review {
        string title;
        int rating;
    };
    
    bool operator<(const Review &r1, const Review &r2);
    bool worseThan(const Review &r1, const Review &r2);
    bool FillReview(Review &rr);
    void ShowReview(const Review &rr);
    
    int main()
    {
        vector<Review> books;
        Review temp;
        while(FillReview(temp))
            books.push_back(temp);
    
        if(books.size() > 0)
        {
            cout<<"size: "<<books.size()<<" ratings:
    rating	book
    ";
            for_each(books.begin(), books.end(), ShowReview);
    
            sort(books.begin(), books.end());
            cout<<"sort by title: 
     rating	book
    ";
            for_each(books.begin(), books.end(), ShowReview);
    
            sort(books.begin(), books.end(), worseThan);
            cout<<"sort by rating: 
     rating	book
    ";
            for_each(books.begin(), books.end(), ShowReview);
    
            random_shuffle(books.begin(), books.end());
            cout<<"sort shuffle: 
     rating	book
    ";
            for_each(books.begin(), books.end(), ShowReview);
    
            random_shuffle(books.begin(), books.end());
            cout<<"sort shuffle2: 
     rating	book
    ";
            for_each(books.begin(), books.end(), ShowReview);
    
        }
        else
            cout<<"No enteris. ";
    
        cout<<"Bye. 
    ";
        return 0;
    }
    
    bool operator<(const Review &r1, const Review &r2)
    {
        if(r1.title < r2.title)
            return true;
        else if(r1.title == r2.title && r1.rating < r2.rating)
            return true;
        else
            return false;
    }
    
    bool worseThan(const Review &r1, const Review &r2)
    {
        if(r1.rating < r2.rating)
            return true;
        else
            return false;
    }
    
    bool FillReview(Review &rr)
    {
        cout<<"enter book title: ";
        getline(cin, rr.title);
        if(rr.title == "q")
            return false;
    
        cout<<"enter book rating: ";
        cin>>rr.rating;
        if(!cin)
            return false;
    
        while(cin.get() != '
    ')
            continue;
    
        return true;
    }
    
    void ShowReview(const Review &rr)
    {
        cout<<rr.rating<<"	"<<rr.title<<endl;
    }

    list

    关联容器

    关联容器是对容器的改进,将值与键相关联并使用键查找值,提供了快速查找元素机制。对于容器X,X::value_type用于获取容器值的数据类型,X::key_type用于获取键的数据类型,关联容器通常是通过树实现的。

    #include <iostream>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <iterator>
    
    int main()
    {
        using namespace std;
    
        const int N = 6;
        string s1[N] = {"atest","aetst","aestt","aetts","atset","atets"};
        string s2[N] = {"bingy","bany","bfood","belegant","bdeliver","bfor"};
    
        set<string> A(s1, s1+N);
        set<string> B(s2, s2+N);
    
        ostream_iterator<string, char> out(cout, " ");
        cout<<"Set A";
        copy(A.begin(), A.end(), out);
        cout<<endl;
    
        cout<<"Set B";
        copy(B.begin(), B.end(), out);
        cout<<endl;
    
        cout<<"Union of A and B:
    ";
        set_union(A.begin(), A.end(), B.begin(), B.end(), out);
        cout<<endl;
    
        cout<<"Intersection of A and B:
    ";
        set_intersection(A.begin(), A.end(), B.begin(), B.end(), out);
        cout<<endl;
    
        cout<<"Difference of A and B:
    ";
        set_difference(A.begin(), A.end(), B.begin(), B.end(), out);
        cout<<endl;
    
        set<string> C;
        cout<<"Set C:
    ";
        set_union(A.begin(), A.end(), B.begin(), B.end(), insert_iterator<set<string> > (C, C.begin()));
        copy(C.begin(), C.end(), out);
        cout<<endl;
    
        string s3("grungy");
        C.insert(s3);
        cout<<"Set C after insertion:
    ";
        copy(C.begin(), C.end(), out);
        cout<<endl;
    
        copy(C.lower_bound("ghost"),C.upper_bound("spook"), out);
        cout<<endl;
    
        return 0;
    }

     2.泛型编程和迭代器

    面向对象思想关注数据,而泛型编程思想关注算法,两者的唯一共同点是致力于实现数据抽象和代码重用,根本上差别非常大。泛型编程的核心思想是代码独立于数据类型,模板使泛型函数或类得以实现,STL则带来了通用算法。同时,模板使得算法独立于数据类型,迭代器使得算法独立于容器类型,所以两者是STL的核心

    //array
    double *find(double *a, int n, double &val)
    {
        for(int i=0; i<n; ++i)
        {
            if(val == ar[i])
            {
                return &ar[i]; //
            }
        }
        return 0; //C++11: return nullptr;
    }
    
    //linklist
    Node *find(Node *head, const double &val)
    {
        Node *ret=head;
        while(ret!=0)
        {
            if(ret->data == data)
                return ret;
            ret=ret->next;
        }
        return 0; 
    }
    
    //STL iterator for array
    typedef double* iterator;
    iterator find_it(iterator it, int n, const double &val)
    {
        int i=0;
        while(i<n)
        {
            if(*it == val)
                return it;
            i++;
            it++;
        }
        return 0;
    }
    
    //STL iterator for array II
    typedef double* iterator;
    iterator find_it(iterator begin, iterator end, const double &val)
    {
        iterator it=begin;
        while(it!=end)
        {
            if(*it == val)
                return it;
            it++;
        }
        return end;
    }
    
    //STL iterator for LinkList
    struct Node {
        double data;
        Node *next;
    };
    
    class iterator {
    private:
        Node *node_;
    public:
        iterator() : node_(0) {}
        iterator(Node *node) : node_(node) {}
        double operator*() { return node_->data; }
        iterator &operator++()
        {
            node_ = node_->next;
            return *this;
        }
        iterator operator++(int)
        {
            iterator tmp = *this;
            node_ = node_->next;
            return tmp;
        }
    };
    
    iterator find_it(iterator begin, const double &val)
    {
        iterator it=begin;
        while(it!=0)
        {
            if(*it == val)
                return it;
            it++;
        }
        return 0;
    }

     

  • 相关阅读:
    项目经理必备的8个要素:沟通、总结、懂技术
    完工概率计算总结
    PMP--可能会涉及到的计算题
    六顶思考帽子法
    预测技术
    React.Component与React.PureComponent的区别
    简单理解JavaScript,TypeScript和JSX
    自己常用的linux命令
    ES6 promise 用法
    node的express框架接收get/post请求时,参数获取方式
  • 原文地址:https://www.cnblogs.com/ingy0923/p/8692197.html
Copyright © 2011-2022 走看看