zoukankan      html  css  js  c++  java
  • 关于STL容器

    容器:
    概念:如果把数据看做物体,容器就是放置这些物体的器物,因为其内部结构不同,数据摆放的方式不同,取用的方式也不同,我们把他们抽象成不同的模板类,使用时去实例化它
    分类:
    序列容器、关联容器、容器适配器
    迭代器(iterator):
    为了方便地访问容器内的数据,迭代器应运而生。迭代器和指针具有相同的功能,对于线性容器,我们通过指针自加即可操作容器内的下一个元素,但对于链表等内存不连续的容器,指针“++”显然不能得到理想的结果,于是我们在容器内嵌套了迭代器,不同容器的迭代器重载了相同的运算符(如“++”),使得我们能够以相同的语法格式处理不同容器内的相似问题
     
    在此之前,函数模板和类模板先了解一下.
    模板是为泛型程序设计而生(设计不考虑数据类型的通用代码)
    函数模板:
    template <class T>
    T MIN(T a ,T b)
    {
    return (a>=b)?b:a;
    }
    void main()
    {
    cout<<MIN(3,4)<<endl;
    cout<<MIN(3.3,4.4)<<endl;
    cin.get();
    }
    函数模板还可以重载,编译器会选择最适合的那个,类的成员函数也可以是函数模板
    类模板:
    template <class T>
    class Array
    {
    public:
    Array(int size=0):msize(size)
    {
    pstr = new T[msize];
    }
    ~Array()
    {
    delete []pstr;
    }
    int get_size(void)
    {
    return msize;
    }
    T&operator[](size_t index)
    {
    if(index > msize)
    {
    throw out_of_range("数组下标越界");
    }
    else
    {
    return pstr[index];
    }
    }
    void printArray(void)
    {
    for(int i=0;i<this->get_size();++i)
    {
    cout<<pstr[i]<<endl;
    }
    }
    private:
    T* pstr;
    int msize;
    };
     
    void main()
    {
    Array<int> int_arr(4);
    Array<float> float_arr(4);
    for(int i=0;i<int_arr.get_size();++i)
    {
    int_arr[i]=i+1;
    }
    for(int i=0;i<int_arr.get_size();++i)
    {
    float_arr[i]=1.0*i+5.2;
    }
    int_arr.printArray();
    float_arr.printArray();
    try
    {
    cout<<int_arr[100];
    }
    catch(out_of_range e)
    {
    cout<<e.what()<<endl;
    }
    cin.get();
    }
    一、序列容器vector
    vector表示一个可变长的数组
    #include<vector>
    template <class T>
    void print_vector(vector<T> & vect)
    {
    cout<<vect.size()<<endl;
    for(unsigned int i=0;i<vect.size();++i)
    {
    cout<<vect[i]<<" ";
    }
    cout<<"vect.capacity:"<<vect.capacity()<<endl;
    }
    void main()
    {
    vector<int> v1;
    for(int i=0;i<10;++i)
    {
    v1.push_back(i*i);
    print_vector(v1);
    }
    cin.get();
    }
    容器的大小一旦超过capacity的大小,vector会重新配置内部的存储器,这样原有数据析构,数据元素拷贝到新的内存中去,内存的重新配置会很耗时间,所有一开始构建这个vector时最好就给它分配足够的空间,避免这一过程。
    二、序列容器deque
    和vector一样是可变数组,不同的是deque数据存储在多块连续的内存之中,deque在预留空间存满,插入新元素扩展空间时,不会发生原有数据的拷贝和析构。在数据大小未知时选这个比vector好,用法差不多。
    三、序列容器list
    底层存储结构为双向链表,不支持随机访问,但在任意位置插入元素都是高速的,由于其链表结构,使其拥有一些其它STL容器没有的成员函数,且更加高效
    四、关联容器set、multiset
    set 即集合,声明如下:
    template<class  T, class  Pr = less<T>, class  A = allocator<A> >
    class set ;
    第一个为集合元素类型,第二个为其排序方式,默认为less,从小到大的顺序,第三个用于内存分配,一般不用管。
    multiset 允许重复元素的存在,其余与set大致相同
    5、关联容器map
    话不多说,这个比较常用。这是在教程上看到的一个比较实用的统计单词个数的例子
    #include<fstream>
    #include<sstream>
    #include<map>
    #include<string>
    template <class T>
    void print_map(T & m)
    {
    T::iterator it = m.begin();
    for(;it!=m.end();++it)
    {
    cout<<it->first<<":"<<it->second<<endl; //first key,second value
    }
    }
    void main()
    {
    ifstream in("c://Users/cetc/Desktop/aa.txt"); //文件流
    stringstream ss;
    char c;
    while((c=in.get())!=-1)
    {
    if(!(c>='A'&&c<='Z'||c>='a'&&c<='z'))
    c=' ';
    ss.put(c); //写入流中
    }
    string word;
    map<string,int> words;
    while(ss>>word) //从流向word中写入值,若key相同,则value加一1
    ++words[word];
    print_map(words);
    cin.get();
    }
    6、关联容器multimap
    允许一对多,不再支持[]运算符
    7.容器适配器 stack
    template<class  T , class  C = deque<T> >
    class stack ;
    先进后出的数据结构(栈)
    #include<stack>
    #include<list>
     
    void main()
    {
    stack<int> s1;
    stack<char,list<char>> s2;
    for(int i=0;i<5;++i)
    {
    s1.push(i+65);
    s2.push(i+65);
    }
    while(!s1.empty()) //s2应该分开的,这里不弄了
    {
    cout<<s1.top()<<endl;
    cout<<s2.top()<<endl;
    s1.pop();
    s2.pop();
    }
    cin.get();
    }
    8.容器适配器 queue 和 priority_queue
    template<class  T , class  C = deque<T> >
    class queue ;
    先进先出(队列),3种序列容器中不能用vector,不能使用vector适配的原因是,vector只能从一端进行高速的插入和删除数据。priority_queue表示有顺序的queue。
    不积跬步,无以至千里。
  • 相关阅读:
    vi编辑器命令大全
    Ubuntu环境搭建svn服务器
    Visual Studio中“后期生成事件命令行” 中使用XCopy命令
    解决 Visual Studio For Mac 还原包失败问题
    [Win10应用开发] 如何使用Windows通知
    [Win10应用开发] 使用 Windows 推送服务
    如何使用 PsExec 执行远程命令
    如何在调试Window App时,触发 Suspending ,Resuming 等事件
    如何 “解决” WPF中空域问题(Airspace issuse)
    浅谈可扩展性框架:MEF
  • 原文地址:https://www.cnblogs.com/doulcl/p/10003431.html
Copyright © 2011-2022 走看看