[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;
}

 

原文地址:https://www.cnblogs.com/ingy0923/p/8692197.html