C++ 容器

/*
@note: 学习C++泛型编程
@date: 2017-11-16
@author: cloudren
*/

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector> 
#include <deque>  
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <typeinfo>

using namespace std;

template <class T>
void print(T t)
{
    for(auto a:t)
        cout<<a<<endl;
}

//2. 迭代器 
//3. 容器 
struct ContainsString;//前置声明

//vector

template <typename T=int>
void vector_test()
{
    std::vector<T> v;
    std::vector<T> v2(2);
    std::vector<T> v3(2, 10);
    std::vector<T> v4(v3);
    int nArr[]={1,2,3,4,5,6,7,8,9,10};
    std::vector<int> v5(nArr, nArr+10);

    v3.push_back(16);
    v3.push_back(17);
    cout<<v3.size()<<endl; //容量大小4 自动增长 

    for(auto a:v3)
        cout<<a<<endl;


    cout<< (v.empty()?"v is empty" :"v is not empty")<<endl;
    try
    {
        cout<< v3[6] << endl;//不抛出异常 访问越界! 
        cout<< v3.at(10)<<endl; //抛出异常 
    }
    catch(std::exception e)
    {
        cerr << e.what() << endl;
    }

    v3.pop_back();//弹出尾部元素 

    v3.erase(v3.end()-1) ; //删除最后一个元素 
    v3.clear();//清除所有元素 
    for( auto a:v3)
        cout<< a <<endl ;
    //通过一个条件函数删除某个元素 用户自定义的条件返回true或者false 
    //eg: remove_if
    std::vector<std::wstring> v6;
    v6.push_back(L"Std template lib");
    v6.push_back(L"The C++ Programming Language");
    v6.push_back(L"Windows Internals"); 
    v6.push_back(L"Programming Applications for Windows");  
    v6.push_back(L"Design Patterns");   
    v6.push_back(L"Effective C++"); 
    v6.push_back(L"More Effective C++");    
    v6.erase(std::remove_if(v6.begin(),v6.end(),ContainsString(L"C++")), v6.end()); 
    /*
    typedef std::vector<std::wstring>::iterator ITER;
    for(ITER it=v6.begin(); it != v6.end(); it++)
        cout<< *it <<endl;//这里有问题 应该跟wstring有关系 需要研究下 
    cout<<L"111111111111111"<<endl; 
    */

}

//定义筛选器 一元函数对象unary_function是什么 需要研究下 
struct ContainsString:public std::unary_function<std::wstring, bool>
{
    ContainsString(const std::wstring &wszMatch):m_wszMatch(wszMatch){}

    bool operator() (const std::wstring &wszStringToMatch) const
    {
        return (wszStringToMatch.find(m_wszMatch) != -1 );
    }
    std::wstring m_wszMatch; 
};

//deque


void deque_test()
{
    deque<int> dq={1,2,3,4,5};//双向队列
    dq.push_back(6);
    dq.push_front(0);
    //dq.pop_back();
    dq.pop_front();
    print(dq);
}


//list

void list_test()
{
    list<int> l1;//双向链表 
    list<int> l2(10);
    list<int> l3(10,8);
    list<int> l4(l3);
    int nArr[]={1,2,3,4,5,6,7,8,9};
    int nArr2[]={11,12,13,14,15,16,17,18,19};
    list<int> l5(nArr, nArr+9);
    list<int> l6(nArr2, nArr2+9);
    l5.splice(l5.begin(), l3, l3.begin(), l3.end()); //8888888888123456789 
    print(l5);
    cout<<"====================================="<<endl;
    #if 0
    list<int>::iterator it=l5.end();
    std::advance(it, -5);
    cout<<*it<<endl;
    #endif
//  l5.splice(it, l3, l3.begin(), l3.end()); //12345678988888888888 (X splice的调用好像有问题!)  __position is in [__first,__last).
    l5.splice(l5.begin(), l3, l3.begin(), l3.end()); //12345678988888888888 (X splice的调用好像有问题!)  __position is in [__first,__last).
    print(l5);
    cout<<"====================================="<<endl;    
    print(l3);
    cout<<"====================================="<<endl;
    cout<<l5.size()<<endl;
    cout<<"====================================="<<endl;
    l5.splice(l5.begin(), l6, l6.begin(), l6.end()); //12345678988888888888 (X splice的调用好像有问题!)  __position is in [__first,__last).
    print(l6);
    print(l5);
}

//stack 先入后出
void stack_test()
{
    //push pop top 
    stack<int> s1;//STl stack底层是以deque为默认结构的 template <class _Ty, class _Container=deque<_Ty> > class stack {...};
    //s1.iterator 错误  stack不允许遍历,故其没有iterator
    stack<int,list<int> > s2;
    s2.push(1);
    s2.push(2);
    std::wcout<< s2.size() << endl;
    std::wcout<< s2.top() << endl;
    s2.pop();
    std::wcout<< s2.top() << endl;

} 

//queue  FIFO
void queue_test()
{
    //pop push front back
    //只能访问最前或者最后元素 不允许遍历
    //queue底层是以deque为默认结构的 template <class _Ty, class _Container=deque<_Ty> > class queue {...};
    queue<int,list<int> > s2;
    s2.push(1);
    s2.push(2);
    std::wcout<< s2.size() << endl;
    std::wcout<< s2.front() << endl;
    std::wcout<< s2.back() << endl;

    //print(s2);//error 不允许遍历 错误! 
    s2.pop();

}

关联容器/
struct Employee{
    Employee(){}
    Employee(const wstring& wszName):Name(wszName){
    }
    std::wstring Name;
};

struct ReverseId:public std::binary_function<int, int, bool>  //三个参数 int代表key1的类型, int代表key2的类型, bool是返回值的类型 
{
    bool operator()(const int &key1, const int &key2) const{//运算符重载  自定义排序行为 
        return (key1<=key2)?false:true;
    }
};

void map_test()
{
    //key/value pair
    //不允许有重复的key    
    //map存储的对象必须是具备可排序性的
    /*
    template <class _Kty,  class _Ty, class _pr=less<_Kty>,
                class _Alloc=allocator<pair<const _Kty, _Ty> >
    class map{...};
    默认采用less定义排序行为
    可以采用自定义排序行为(仿函数) 
    */
    const int size = 3;
    const std::pair<int, Employee> items[size]={
        std::make_pair(1, Employee(L"Tom")),
        std::make_pair(2, Employee(L"Jim")),
        std::make_pair(3, Employee(L"John"))
    };

    std::map<int, Employee, ReverseId> map1(items, items+3);
    map1.insert(make_pair(4, Employee(L"Cloud")));
    map1.insert(make_pair(5, Employee(L"Lora")));

    map1.erase(1);//key erase

    std::map<int,Employee>::iterator it1=map1.begin();
    map1.erase(it1);
    map1.erase(map1.begin());

    Employee &e = map1[2];
    wcout<< e.Name<<endl;//Jim  对于wstring使用wcout进行输出! 
    cout<< map1.size()<<endl;

    //一般的map 
    const std::pair<int, int> items2[5]={
        std::make_pair(1,10),
        std::make_pair(2,20),
        std::make_pair(3,30),
        std::make_pair(4,40),
        std::make_pair(5,50),
    };
    map<int,int> map2(items2, items2+5);
    map2.erase(map2.begin());//iterator 
    map2.erase(3);//key
    std::map<int,int>::iterator it=map2.begin();
    for(; it != map2.end();it++)
        cout<< it->second <<endl;

    //multimap 允许key重复 
}


//set
class Person{
    public:
        Person(const std::wstring &wszName, const size_t nId):m_Name(wszName), m_Id(nId){
        }   
        const wstring& GetName() const {return m_Name;}
        const size_t GetId() const {return m_Id;}
    wstring m_Name;
    size_t  m_Id;
}; 

struct PersonIdComparer:public std::binary_function<Person, Person, bool>{
    bool operator()(const Person& p1, const Person &p2)  const{
        return (p1.GetId() < p2.GetId())?true:false;
    }
};

struct PersonNameComparer:public std::binary_function<Person, Person, bool>{
    bool operator()(const Person& p1, const Person &p2)  const{
        return (p1.GetName() < p2.GetName())?true:false;
    }   
};




void set_test()
{
    //set关联容器 存储对象既是key也是value
    //不允许有重复key
    //set 存储对象必须是可排序的 
        /*
    template <class _Kty, class _pr=less<_Kty>, class _Alloc=allocator<pair<const _Kty> >
    class set{...};
    默认采用less定义排序行为
    可以采用自定义排序行为(仿函数) 
    */
    const size_t nSize=3;
    const Person personArr[nSize]={
        Person(L"Tom", 1),
        Person(L"Tom2", 12),
        Person(L"Tom3", 123)
    };
    std::set<Person, PersonIdComparer> ps1(personArr, personArr + nSize);
    ps1.insert(Person(L"Tom4", 1234));
    //std::set<Person, PersonIdComparer>::iterator it=ps1.begin();
    //std::advance(it, 1);
    //ps1.erase(it);

    cout<<"===============================================\n";
    std::set<Person, PersonIdComparer> ps2;
    ps2.insert(Person(L"Apple0", 0));
    ps2.insert(Person(L"Jerry", 6));

    //相关算法 std::set_union   std::set_intersection std::set_difference

    #if 0
    set<Person, PersonIdComparer> dst;
    std::insert_iterator<set<Person, PersonIdComparer> > ii(dst, dst.begin());
    std::set_union(ps1.begin(), ps1.end(), ps2.begin(), ps2.end(), ii, PersonIdComparer());//求并集 
    cout<< dst.size()<<endl;
    typedef set<Person, PersonIdComparer>::iterator _MyIter;
    _MyIter it2=dst.begin();
    for(; it2!= dst.end(); it2++)
        wcout<< it2->GetName()<<endl;
    #endif

    #if 0
    {

        std::set<Person, PersonIdComparer> ps3;
        ps3.insert(Person(L"Tom2", 12));
        ps3.insert(Person(L"Tom3", 123));

        set<Person, PersonIdComparer> dst;
        std::insert_iterator<set<Person, PersonIdComparer> > ii(dst, dst.begin());
        std::set_intersection(ps1.begin(), ps1.end(), ps3.begin(), ps3.end(), ii, PersonIdComparer());//求交集 
        cout<< dst.size()<<endl;
        typedef set<Person, PersonIdComparer>::iterator _MyIter;
        _MyIter it2=dst.begin();
        for(; it2!= dst.end(); it2++)
            wcout<< it2->GetName()<<endl;
    }
    #endif

    #if 0
    {
        std::set<Person, PersonIdComparer> ps3;
        ps3.insert(Person(L"Apple0", 0));
        ps3.insert(Person(L"Jerry", 6));
        ps3.insert(Person(L"Tom2", 12));
        ps3.insert(Person(L"Tom3", 123));
        set<Person, PersonIdComparer> dst;
        std::insert_iterator<set<Person, PersonIdComparer> > ii(dst, dst.begin());
        std::set_difference(ps1.begin(), ps1.end(), ps3.begin(), ps3.end(), ii, PersonIdComparer());//求差集 (ps1 - ps1交ps3)
        cout<< dst.size()<<endl;
        typedef set<Person, PersonIdComparer>::iterator _MyIter;
        _MyIter it2=dst.begin();
        for(; it2!= dst.end(); it2++)
            wcout<< it2->GetName()<<endl;
    }
    #endif
    #if 1 //修改某个元素的name 
    typedef set<Person, PersonIdComparer>::iterator _MyIter;
    _MyIter it2=ps1.find(Person(L"Tom", 1));
    if( it2 != ps1.end())
    {
        const_cast<Person&>(*it2).m_Name=L"Tom Swifftor";  //一定要cast为对象的引用而不是对象本身
        wcout << it2->m_Name << endl;
    }


    #endif


}


int main(void)
{

    //vector_test();
    //deque_test();
    list_test();
    //stack_test();
    //queue_test();
    //map_test();
    //set_test();
    return 0;
}

补:

list::splice函数

list::splice实现list拼接的功能。将源list的内容部分或全部元素删除,拼插入到目的list。

函数有以下三种声明:

void splice ( iterator position, list<T,Allocator>& x );  

void splice ( iterator position, list<T,Allocator>& x, iterator i );

void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );

函数说明:
在list间移动元素, 将x的元素移动到目的list的指定位置,高效的将他们插入到目的list并从x中删除。
目的list的大小会增加,增加的大小为插入元素的大小。x的大小相应的会减少同样的大小。
前两个函数不会涉及到元素的创建或销毁。第三个函数会。
指向被删除元素的迭代器会失效。

@param: position: 目的list的位置,用来标明 插入位置
@param: x: 源list
@param: first,last : x里需要被移动的元素的迭代器。区间为[first, last).包含first指向的元素,不包含last指向的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值