C++ STL(二)

一、关联容器

关联容器有set,multiset,map,multimap

特点:内部元素有序排列,新元素插入位置取决于它的值

在说明关联容器前,需要先介绍以下pair模板,因为map,multimap容器里存放的都是pair模板类对象。

#include <iostream>
using namespace std;

template <class _T1, class _T2>
struct pair
{
    typedef _T1 first_type;
    typedef _T2 second_type;
    _T1 first;
    _T2 second;
    pair(): first(), second() {}
    pair(const _T1 & _a, const _T2 & _b): first(_a), second(_b) { }
    template <class _U1, class _U2>
    pair(const pair<_U1, _U2> & _p):first(_p.first), second(_p.second){ }
};

Pari模板提供了三种构造方法,这里提供了三种构造pair的方式,其中注意下第三种构造方法:

    pair<int, int> p(pair<double, double>(5.5,4.6));
    cout << p.first << p.second;

 

二、multiset和set

1.multiset

multiset类实现代码较复杂,这里了解下模板的定义:

template<class Key, class Pred = less<Key>, class A = allocator<Key>>

这里的Pred变量决定multiset中的元素以何种方式“一个比另一个小”是如何定义的,其缺省类型为less<Key>

less的模板定义:

template<class T>
struct less : public binary_function<T, T, bool>
{
    bool operator()(const T & x, const T & y) const
    {
        return x < y;
    }
};

下面自己编写less函数:

struct MyLess{
    bool operator ()(const A & a1, const A & a2)
    {
        return (a1.n % 10) < (a2.n % 10);
    }
};

通过MyLess函数生成multimap

#include <iostream>
#include <set>

using namespace std;

class A{
public:
    A(int n_):n(n_) {}
    friend bool operator < (const A & a1, const A & a2) {return a1.n < a2.n; }
    friend ostream & operator << (ostream & o, const A & a1){ o << a1.n; return o; }
    friend class MyLess;
private:
    int n;
};

template <class T>
void Print(T first, T second)
{
    for(; first != second; ++first)
        cout << * first << " ";
    cout << endl;
}

struct MyLess{
    bool operator ()(const A & a1, const A & a2)
    {
        return (a1.n % 10) < (a2.n % 10);
    }
};

int main()
{
    double a[] = {11,27,3,51,36};
    multiset<A, MyLess> m1;
    m1.insert(a, a + 5);
    Print(m1.begin(), m1.end());
    return 0;
}

multiset常用的成员函数有

1.iterator insert(const T & val);   将val插入到容器中并返回其迭代器。 

multiset<A> m1;
multiset<A>::iterator pp = m1.insert(5);
cout << * pp;

2.void insert( iterator first,iterator last); 将区间[first,last)插入容器。 

double a[] = {11,27,3,51,36};
multiset<A> m1;
m1.insert(a, a + 5);
Print(m1.begin(), m1.end());

3.iterator find(const T & val); 在容器中查找值为val的元素,返回其迭代器。如果找不到,返回end()

double a[] = {11,27,3,51,36};
multiset<A> m1;
m1.insert(a, a + 5);
if (m1.find(3) != m1.end())
    cout << "found" << endl;

4.int count(const T & val); 统计有多少个元素的值和val相等。 

5.iterator lower_bound(const T & val); 查找一个最大的位置 it,使得[begin(),it) 中所有的元素都比 val 小

6.iterator upper_bound(const T & val); 查找一个最小的位置 it,使得[it,end()) 中所有的元素都比 val 

7.pair<iterator,iterator>  equal_range(const T & val); 同时求得lower_bound和upper_bound

8.iterator erase(iterator it); 删除it指向的元素,返回其后面的元素的迭代器(Visual studio 2010上如此,但是在 C++标准和Dev C++中,返回值不是这样)。

A a[6] = {4, 22, 19, 8, 33, 40};
multiset<A> m1;
m1.insert(a, a + 6);
m1.erase(m1.lower_bound(7),m1.upper_bound(32));
Print(m1.begin(), m1.end());

三、map和multimap

1.multimap的函数部分如下所示:

template<class Key, class T, class Pred = less<Key>, class A = allocator<T>>
class multimap{
    ...
    typedef pair<const Key, T> value_type;
    ...
}

这里的Key代表关键字类型,multimap中的元素由<关键字,值>构成,每个元素又是一个pair对象。在multimap中允许多个元素的关键字相同。

2.multimap示例:

#include <iostream>
#include <map>

using namespace std;

int main()
{
    typedef multimap<int, double, less<int> > mmid;
    mmid pairs;
    cout << pairs.count(15) << endl;

    pairs.insert(mmid::value_type(15, 2.7));
    pairs.insert(mmid::value_type(15,99.3));
    cout << pairs.count(15) << endl;

    pairs.insert(mmid::value_type(30,111.11));
    pairs.insert(mmid::value_type(10,22.22));
    pairs.insert(mmid::value_type(25,33.333));
    pairs.insert(mmid::value_type(20,9.3));

    for(mmid::const_iterator i = pairs.begin(); i != pairs.end();++i)
        cout << i->first << "," << i->second << endl;
}

3.map

template<class Key, class T, class Pred = less<Key>, class A = allocator<T> >
class map{
    ...
    typedef pair <const Key, T> value_type;
    ...
}

map中的元素都是pair模板类对象。关键字(first成员变量)各不相同

下述语句例如:

map<int, double> pairs;
pairs[50] = 5;

如果存在关键字为50的元素,则修改其值为5,若不存在,则插入此元素

4.map示例

#include <iostream>
#include <map>
using namespace std;

template <class Key, class Value>
ostream & operator << (ostream & o, const pair<Key, Value> & p)
{
    o << "(" << p.first << "," << p.second << ")";
    return o;
}

int main()
{
    typedef map<int, double, less<int> > mmid;
    mmid pairs;
    cout << pairs.count(15) << endl;

    pairs.insert(mmid::value_type(15,2.7));
    // make_pair生成一个pair对象
    pairs.insert(make_pair(15,99.3));
    cout << pairs.count(15) << endl;

    pairs.insert(mmid::value_type(20,9.3));
    mmid::iterator i;
    for(i = pairs.begin(); i != pairs.end(); ++i)
        cout << *i << " ";
    cout << endl;

    // 若没有key=40元素,则插入
    int n = pairs[40];
    for(i = pairs.begin(); i != pairs.end(); ++i)
        cout << *i << " ";
    cout << endl;

    pairs[15] = 6.28;
    for(i = pairs.begin(); i != pairs.end(); ++i)
        cout << *i << " ";
    cout << endl;
    return 0;
}

四、容器适配器

1.stack

stack是后进先出的数据结构,只能插入、删除、访问栈顶元素。

可以通过vector,list,deque实现,默认deque,一般来说用vector和deque相对于用list性能较好

template<class T, class Cont = deque<T> >

其操作有:push,pop,top

2.queue

与stack基本类似:

template<class T, class Cont = deque<T> >

注意这里push发生在队尾,pop,top发生在队头。先进先出,同时还有back成员函数返回队尾元素的引用。

3.priority_queue

和queue基本类似,priority_queue 通常用堆排序技术实现,保证最大的元素总是 在最前面。即执行pop操作时,删除的是最大的元素;执行top 操作时,返回的是最大元素的常引用。默认的元素比较器是 less<T>

template <class T, class Container = vector<T>, class Compare = less<T> >

4.示例

#include <queue>
#include <iostream>

using namespace std;

int main()
{
    priority_queue<double> pq1;
    pq1.push(3.2);
    pq1.push(9.8);
    pq1.push(5.4);
    while(!pq1.empty())
    {
        cout << pq1.top() << " ";
        pq1.pop();
    }
    cout << endl;

    priority_queue<double, vector<double>, greater<double> > pq2;
    pq2.push(3.2);
    pq2.push(9.8);
    pq2.push(9.8);
    pq2.push(5.4);
    while( !pq2.empty())
    {
        cout << pq2.top() << " ";
        pq2.pop();
    }
    return 0;
}

这里的empty用于判断适配器是否为空,同时还有size()返回适配器中元素个数。

参考:

《C++ Primer》第五版

郭炜老师的《C++面向对象程序设计》

猜你喜欢

转载自blog.csdn.net/adorkable_thief/article/details/85330327