`
kmplayer
  • 浏览: 498816 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

通用容器4_deque

阅读更多
1,deque特点:
(1)将元素放在多个连续的存储块.
(2)允许在序列两端快速地插入元素,并且在扩展存储区的时候不需要拷贝和析构原来的对象.
(3)deque支持随机访问[],但是速度没有vector快.
2,deque和vector的区别:微不足道.
deque有接口push_front()和pop_front(),而vector没有.
#include <cstddef>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    ifstream in("happy.in");
    vector<string> vstrings;
    deque<string> dstrings;
    string line;
    // Time reading into vector:
    clock_t ticks = clock();
    while(getline(in, line))
        vstrings.push_back(line);
    ticks = clock() - ticks;
    cout << "Read into vector: " << ticks << endl;

    // Repeat for deque:
    ifstream in2("happy.in");
    ticks = clock();
    while(getline(in2, line))
        dstrings.push_back(line);
    ticks = clock() - ticks;
    cout << "Read into deque: " << ticks << endl;
    //deque插入的速度更快

    // Now compare indexing: 加入行号
    ticks = clock();
    for(size_t i = 0; i < vstrings.size(); i++)
    {
        ostringstream ss;
        ss << i;
        vstrings[i] = ss.str() + ": " + vstrings[i];
    }
    ticks = clock() - ticks;
    cout << "Indexing vector: " << ticks << endl;

    ticks = clock();
    for(size_t j = 0; j < dstrings.size(); j++)
    {
        ostringstream ss;
        ss << j;
        dstrings[j] = ss.str() + ": " + dstrings[j];
    }
    ticks = clock() - ticks;
    cout << "Indexing deque: " << ticks << endl;
    //vector索引的速度更快

    // Compare iteration
    ofstream tmp1("tmp1.tmp"), tmp2("tmp2.tmp");
    ticks = clock();
    copy(vstrings.begin(), vstrings.end(), ostream_iterator<string>(tmp1, "\n"));
    ticks = clock() - ticks;
    cout << "Iterating vector: " << ticks << endl;
    ticks = clock();
    copy(dstrings.begin(), dstrings.end(), ostream_iterator<string>(tmp2, "\n"));
    ticks = clock() - ticks;
    cout << "Iterating deque: " << ticks << endl;
    //vector使用迭代器更快
}


3,序列容器间的转换
#include <algorithm>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

//读入deque,然后转化为vector
class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;


int main()
{
    int size = 25;
    deque<Noisy> d;
    generate_n(back_inserter(d), size, NoisyGen());

    cout << "\n Converting to a vector(1)" << endl;
    vector<Noisy> v1(d.begin(), d.end());//v1不会导致多次内存分配.

    cout << "\n Converting to a vector(2)" << endl;
    vector<Noisy> v2;
    v2.reserve(d.size());//先预先分配好大小,实际上和v1完全一致.
    v2.assign(d.begin(), d.end());

    cout << "\n Cleanup" << endl;
}


4,
#include <cstdlib>
#include <deque>
#include <iostream>
using namespace std;

//读入deque,然后转化为vector
class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;

int main()
{
    int size = 100;
    deque<Noisy> dn;
    Noisy n;
    for(int i = 0; i < size; i++)
        dn.push_back(n);
    cout << "\n cleaning up "<< endl;
    return 0;
}


5,at比索引操作符[]代价更大.
#include <ctime>
#include <deque>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    long count = 1000;
    int sz = 1000;

    vector<int> vi(sz);
    clock_t ticks = clock();
    for(int i1 = 0; i1 < count; i1++)
        for(int j = 0; j < sz; j++)
            vi[j];
    cout << "vector[] " << clock() - ticks << endl;

    ticks = clock();
    for(int i2 = 0; i2 < count; i2++)
        for(int j = 0; j < sz; j++)
            vi.at(j);
    cout << "vector::at() " << clock()-ticks <<endl;

    deque<int> di(sz);
    ticks = clock();
    for(int i3 = 0; i3 < count; i3++)
        for(int j = 0; j < sz; j++)
            di[j];
    cout << "deque[] " << clock() - ticks << endl;

    ticks = clock();
    for(int i4 = 0; i4 < count; i4++)
        for(int j = 0; j < sz; j++)
            di.at(j);
    cout << "deque::at() " << clock()-ticks <<endl;

    try
    {
        di.at(vi.size() + 1);
    } catch(...) { //捕捉所有异常
        cerr << "Exception thrown" << endl;
    }
    return 0;
}
分享到:
评论

相关推荐

    传智播客扫地僧视频讲义源码

    11_copy构造函数调用时机4_函数返回值是匿名对象的去和留的剖析_传智扫地僧 12_构造和析构的重点整理 13_构造和析构总结 14_中午课程复习 15_构造函数的调用规则研究 16_浅拷贝问题抛出 17_浅拷贝问题分析_传智扫地...

    【Python】详解 collections 模块之 namedtuple 函数

    collections 作为 Python 的内建集合模块,实现了许多十分高效的特殊容器数据类型,即除了 Python 通用内置容器: dict、list、set 和 tuple 等的替代方案。在 IDLE 输入 help(collections) 可查看帮助文档,其中...

    cstl--国人写的挺不错的C语言通用数据结构和常用算法库,支持一个

    cstl是使用C语言编写的一个通用的数据结构和常用的算法库,它模仿SGI STL的接口和实现,支持vector, list, deque等等常用的数据结构,同时还支持排序,查找,划分等常用的算法,此外cstl也包含迭代器的类型,它作为...

    C++标准程序库STL的架构

    4 通用工具 9 4.1 简介 9 4.1.1 类别 9 4.1.2 头文件 9 4.2 Pairs 9 4.2.1 简介 9 4.2.2 示例 9 4.3 auto_ptr 10 4.3.1 作用 10 4.3.2 引入原因 10 4.3.3 声明 10 4.3.4 auto_ptr拥有权的转移 10 4.3.5 示例 11 ...

    C++STL程序员开发指南【可搜索+可编辑】

    2-4-4 C廿异常处理机制.............................................. 97 2-4-5 类的异常处理.................................................. 99 2-5 小结· · · · · · ·................................

    一个简单的队列类和栈类

    队列类的实现采用了 C++ 标准模板库 (STL) 中的 deque 容器作为底层存储结构。deque 是一种双端队列,可以在两端高效地进行插入和删除操作,因此非常适合实现队列的入队和出队操作。队列类提供了以下主要方法: - `...

    100-days-of-code:存储库可跟踪Python中的#100DaysOfCode挑战

    元组违约柜台双端队列collections模块实现了专用的容器数据类型,为Python的通用内置容器 , list , set和tuple提供了替代方法。 namedtuple() 用于使用命名字段创建元组子类的工厂函数deque 类似于列表的容器,两...

    本人精心收集,c++头文件一览

    deque&gt; //STL 双端队列容器 #include &lt;exception&gt; //异常处理类 #include &lt;fstream&gt; #include &lt;functional&gt; //STL 定义运算函数(代替运算符) #include &lt;limits&gt; #include &lt;list&...

    分享C++面试中string类的一种正确写法

    能用作标准库容器的元素类型,即 vector/list/deque 的 value_type。(用作 std::map 的 key_type 是更进一步的要求,本文从略)。 换言之,你的 String 能让以下代码编译运行通过,并且没有内存方面的错误。 代码...

    libcstl数据结构和常用的算法库

    libcstl是使用C语言编写的一个通用的数据结构和常用的算法库,它模仿SGI STL的接口和实现,支持vector,list,deque等等常用的数据结构,同时还支持排序,查找,划分等常用的算法,此外libcstl也包含迭 代器的类型,它...

    C和C++头文件对比一览

    #include &lt;deque&gt; //STL 双端队列容器 #include &lt;exception&gt; //异常处理类 #include #include &lt;functional&gt; //STL 定义运算函数(代替运算符) #include #include &lt;list&gt; //STL 线性列表容器 #include &lt;map&gt; ...

    摩托罗拉C++面试题

    STL有7种主要容器:vector,list,deque,map,multimap,set,multiset. 17.你如何理解MVC。简单举例来说明其应用。 MVC模式是observer 模式的一个特例,典型的有MFC里面的文档视图架构。 18,多重继承如何消除向上继承...

Global site tag (gtag.js) - Google Analytics