第6章:顺序容器及其它类型容器

1,顺序容器和操作
2,源码

#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>

/*
顺序容器:
1,vector:可变大小数组,支持快速随机访问,在尾部之外的位置插入或删除元素很慢
2,deque: 双端列队,支持快速随机访问,在头尾位置插入和删除速度很快
3,list:双向链表,只支持双向顺序访问,在list中任何位置进行插入或删除操作速度都很快
4,forward_list: 单向链表,只支持单向顺序访问,在链表任何为hi在进行插入或删除操作速度都很快
5,array:固定大小数组,支持快速随机访问,不能添加或删除元素
6,string:与vector相似的容器,但专门用于保存字符,随机访问快,在尾部插入或删除快
类型别名,迭代器类型:
iterator:此容器类型的迭代器类型
const_iterator:可以读取元素,但不能修改元素的迭代器类型
size_type:无符号整数类型,足够保存此中容器类型最大可能容器的大小
difference_type:带符号整数类型,足够保存两个迭代器之间的距离
value_type:元素类型
reference:元素的左值类型:与value_typed&含义相同
const_reference:元素的const左值类型
迭代器
迭代器是使用容器的基础,除了下标运算迭代器是一种更加通用的机制
*/



using namespace std;
int main()
{
    /*容器大小-----------------------------------------------------------------------------------------*/
    //只用顺序容器的的构造函数才能接受参数大小
    const vector<int> num = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto num_beg = num.cbegin();
    auto num_end = num.cend();

    cout << "num.size() = " << num.size() << endl;              //元素个数
    cout << "num.max_size() = " << num.max_size() << endl;      //最大个数
    cout << "num.empty() = " << num.empty() << endl;            //判断是否为空
    while (num_beg != num_end)
    {
       cout << *num_beg <<" ";
       num_beg++;
    }
    cout << endl;



    /*迭代器类型获得-------------------------------------------------------------------------------------*/
    list<string>      str = {"a", "an", "and"};                 //定义一个容器

    //atuo与begin end结合使用时,获得的迭代器类型依赖于容器类型,与我们想如何使用迭代器无关
    auto it1 = str.begin();                                //list<string>::iterator                迭代器
    auto it2 = str.rbegin();                               //list<string>::reverse_iterator        反向迭代器
    auto it3 = str.cbegin();                               //list<string>::const_iterator          const迭代器
    auto it4 = str.crbegin();                              //list<string>::const_reverse_iterator  反向 const迭代器



    /*容器类型拷贝-----------------------------------------------------------------------------------------*/
    list<string>         name = {"xiaohua", "xiaotao", "xiaojun"};   //定义 name 列表
    list<string>         name_bak(name);                             //把 name 的内容拷贝给 namebak

    vector<const char *> age = {"25", "26", "27"};

    auto age_beg = age.begin();
    age_beg++;
    deque<string>        age_haf(age.begin(), age_beg);
    auto age_haf_beg = age_haf.begin();
    auto age_haf_end = age_haf.end();
    while (age_haf_beg != age_haf_end)
    {
        cout << *age_haf_beg++ <<endl;
    }

    forward_list<string> age_bak(age.begin(), age.end());            //可以把const char *转换成string
    auto age_bak_beg = age_bak.begin();
    auto age_bak_end = age_bak.end();
    while (age_bak_beg != age_bak_end)
    {
       cout << *age_bak_beg++ << " ";
    }
    cout << endl;



    /*顺序容器默认大小定义----------------------------------------------------------------------------------*/
    vector<int>       invec(10, 1);                                       //初始化10个int元素每个初始化为1
    list<string>      slist(10, "HI");                                    //初始化10个string元素每个初始化为“HI”
    forward_list<int> flist(10, 2);                                       //初始化10个int元素每个初始化为1
    deque<string>     dstr(10, "a");                                      //初始化10个string元素每个初始化为“a”

    array<int, 10>::size_type    iarray;                                  //数组在使用的时候必须指定类型和大小



    /*赋值和swap-----------------------------------------------------------------------------------------*/
    array<int, 10>  array_1 = {0, 1, 2, 3, 4, 5, 6, 7, 8 ,9};
    array<int, 10>  array_2 = {0};
    auto array_1_beg = array_1.begin();
    auto array_1_end = array_1.end();
    auto array_2_beg = array_2.begin();
    auto array_2_end = array_2.end();

    //array_1 和 array_2交换数据
    array_2.swap(array_1);
    while (array_1_beg != array_1_end)
    {
        cout << *array_1_beg++ << " ";
    }
    cout << endl;
    while (array_2_beg != array_2_end)
    {
        cout << *array_2_beg++ << " ";
    }
    cout << endl;


    vector<int>  vector_1 = {0, 1, 2, 3, 4, 5, 6, 7, 8 ,9};
    vector<int>  vector_2(10, 0);
    auto vector_2_beg = vector_2.begin();
    auto vector_2_end = vector_2.end();

    //拷贝数据 数组没有assign函数
    vector_2.assign(vector_1.begin(), vector_1.end());
    while (vector_2_beg != vector_2_end)
    {
        cout << *vector_2_beg++ << " ";
    }
    cout << endl;


    /*关系运算符-----------------------------------------------------------------------------------------*/
    vector<int>     vectro_cmp1 = {0,1,2,3,4,5,6};
    vector<int>     vectro_cmp2 = {0,1,2,5};
    vector<int>     vectro_cmp3 = {0,1,2,3,4};
    vector<int>     vectro_cmp4 = {0,1,2,3,4,5,6};

    //cmp2与cmp1不同之处在于cmp2[3] > cmp1[3]
    cout << (vectro_cmp2 > vectro_cmp1) << endl;               //true
    cout << (vectro_cmp1 < vectro_cmp3) << endl;               //false
    cout << (vectro_cmp1 == vectro_cmp4) <<endl;               //true




    return 0;
}
#include <iostream>
#include <list>
#include <vector>
#include <deque>
#include <forward_list>
#include <array>
#include <string>

/*
顺序容器操作:
1,除了Array外,所有标准库容器都提供灵活的内存管理,在运行时可以动态添加或删除元素改变容器大小
2,操作命令:
    forward_list:有自己专用版本的insert和emplace;不支持push_back和emplace_back
    vector和string:不支持push_front和emplace_front
    c.push_back(t)
    c.emplace_back(arg)
    c.push_front(t)
    c.emplace_front(arg)
    c.insert(p, t)         //插入一个 t
    c.emplace(p, arg)
    c.insert(p, n, t)      //插入n个
3,push与emplace区别:
    push:   当调用push时,我们将元素类型的对象传递给他们,这些对象被拷贝到容器中
    emplace:当调用emplace时,则是将参数传递给元素类型的构造函数,emplace成员使用这些参数在容器管理的内存空间中直接
             构造元素
    区别:push和emplace都会创建新的对象,emplace会在容器管理的内存空间中直接创建对象,push则会创建一个局部临时对象,
         并将其压入容器中,emplace效率更高
4,元素访问:
   c.front(); c.back(); c.front(); c[n], c.at(n)
5,元素删除:
   forward_list有特殊版本的erase
   forward_list不支持pop_back;
   vector string不支持pop_front
   c.pop_back():删除c中尾元素
   c.pop_front():删除c中首元素
   c.erase(p):删除迭代器p所指定的元素,返回一个指向被删元素之后元素的迭代器
   c.erase(b,3):删除迭代器b和e所指定环卫内的元素返回一个指向最后一个删除元素之后元素的迭代器
   c.clear():删除c中的所有元素,返回void
6,重新定义容器大小:
   c.resize()
*/



using namespace std;
int main()
{

    /*push_back除了array和forward_list每个容器都支持---------------------------------------------------------------*/
    list<int> list_num;

    for (int i=0; i<4; i++)
    {
        list_num.push_back(i);
    }
    //如果beg end放在for循环前则会beg == end,因为此时列表中还没有值
    auto list_num_beg = list_num.begin();
    auto list_num_end = list_num.end();
    while (list_num_beg != list_num_end)
    {
        cout << *list_num_beg++ << " ";
    }
    cout << endl;


    /*push_front除了vectro和string每个容器都支持-----------------------------------------------------------------*/
    deque<int> deque_num;

    for (int i=0; i<4; i++)
    {
        deque_num.push_front(i);
    }
   //如果beg end放在for循环前则会beg == end
    auto deque_num_beg = deque_num.begin();
    auto deque_num_end = deque_num.end();
    while (deque_num_beg != deque_num_end)
    {
        cout << *deque_num_beg++ << " ";
    }
    cout << endl;


    /*insert在特定的位置添加元素-------------------------------------------------------------------------------*/
    list<string> list_str;

    list_str.push_front("xiaohua");
    list_str.push_back("xiaotao");
    list_str.insert(list_str.begin(), "xiaogou");

    auto list_str_beg = list_str.begin();
    auto list_str_end = list_str.end();
    while (list_str_beg != list_str_end)
    {
        cout << *list_str_beg++ << " ";
    }
    cout << endl;



    /*insert插入范围内元素----------------------------------------------------------------------------------*/
    vector<string> list_name;
    vector<string> list_name_bak = {"xiao tao", "xiao mei", "xiao jun"};

    list_name.insert(list_name.begin(), 2, "xiao hua");
    list_name.insert(list_name.end(), ++list_name_bak.begin(), list_name_bak.end());
    list_name.insert(list_name.end(), {"xiao li", "xiao mei"});
    list_name.insert(list_name.begin(), list_name.begin(), list_name.end());

    auto list_name_beg = list_name.begin();
    auto list_name_end = list_name.end();
    while (list_name_beg != list_name_end)
    {

        cout << *list_name_beg++ << "; ";
    }
    cout << endl;



    /*emplace_back, emplace, emplace_front----------------------------------------------------------*/
    vector<string> vector_age;
    vector_age.emplace_back("18");



    /*访问元素----------------------------------------------------------------------------------------*/
    vector<string> vector_lev;

    vector_lev.emplace_back("P6");
    vector_lev.emplace_back("P7");
    vector_lev.emplace_back("P8");
    vector_lev.emplace_back("P9");

    cout << vector_lev.front() << endl;
    cout << vector_lev.back() << endl;
    cout << vector_lev[1] << endl;
    cout << vector_lev.at(2) << endl;

    /*删除元素---------------------------------------------------------------------------------------*/
    list<int> list_num2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    list_num2.pop_back();
    list_num2.pop_front();
    
    auto list_it  = list_num2.begin();
    while(list_it != list_num2.end())
    {
    	if (*list_it % 2)
      {
      	//删除单个元素
        list_it = list_num2.erase(list_it);
      }
      else
      {
      	++list_it;
      }	
    }
    //删除指定个数元素
    list_num2.erase(list_num2.begin(), ++list_num2.begin());
    //清空元素
    list_num2.clear();
    
    
    /*改变容器大小------------------------------------------------------------------------------------*/
    list<int> list_resize = {0,1,2,3,4,5,6,7,8,9};
    list_resize.resize(15);                         //将5个值为0的元素添加到list_resize的末尾
    list_resize.resize(25,-1);											//将10个值为-1的元素添加到list_resize的末尾
    list_resize.resize(5);                          //从list_resize末尾删除20个元素
    
    
    
    /*容器操作可能使迭代器功能失效--------------------------------------------------------------------*/
    vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
    auto iter = vi.begin();
    

    //在erase后不必递增迭代器,因为erase返回的迭代器已经指向序列中下一个元素
    //在insert后,需要递增迭代器两次,insert在给定位置之前插入新元素,然后返回指向新插入元素的迭代器
    //不要保存end返回的迭代器,在添加或删除后,原来返回的迭代器总会失效
    while (iter != vi.end())
    {
    	if (*iter % 2)
    	{
            iter = vi.insert(iter, *iter);           //复制当前元素
            iter += 2;                               //向前移动迭代器,跳过当前元素及插入之前的元素
    	}
    	else
        {
            iter = vi.erase(iter);                  //删除偶数元素,iter指向删除之后的元素
        }
    }
    
    
    

    return 0;
}
#include <iostream>
#include <list>
#include <iterator>
#include <vector>
#include <string>
#include <algorithm>

/*
1,插入迭代器
当我们通过一个插入迭代器进行赋值时,该迭代器调用容器操作来向给定容器的指定位置插入一个元素
back_inserter:创建一个push_back的迭代器
front_inserter:创建一个push_front的迭代器
inserter:创建一个insert的迭代器
2,iosteam迭代器
3,反向迭代器
4,迭代器类别
输入迭代器;输出迭代器;前向迭代器;双向迭代器;随机访问迭代器
5,算法一般明明规则
alg(beg, end, args)
alg(beg, end, dest, args)
alg(beg, end, beg2, args)
alg(beg, end, beg2, end2, args)
6,谓词
一元函数对象:函数参数1个
二元函数对象:函数参数2个
一元谓词 函数参数1个,函数返回值是bool类型,可以作为一个判断式
谓词可以是一个仿函数,也可以是一个回调函数
二元谓词 函数参数2个,函数返回值是bool类型
*/
using namespace std;
int main()
{
    /*插入迭代器---------------------------------------------------------------------------*/
    list<int> num1 = {0,1,2,3,4,5};
    list<int> num2, num3;

    copy(num1.begin(), num1.end(), front_inserter(num2));
    for (const auto &temp_num : num2)
    {
        cout << temp_num << " ";
    }
    cout << endl;
    copy(num1.begin(), num1.end(), inserter(num3, num3.begin()));
    for (const auto &temp_num : num3)
    {
        cout << temp_num << " ";
    }
    cout << endl;


    /*反向迭代器-------------------------------------------------------------------------*/
    vector<int> num4 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    vector<string> buf = {"a", "and", "name", "egg"};

    for (const auto &temp_num : num4)
    {
        cout << temp_num << " ";
    }
    cout << endl;

    for (auto temp_num=num4.crbegin(); temp_num != num4.crend(); ++temp_num)
    {
        cout << *temp_num << " ";
    }
    cout << endl;
    //sort用 "<" 运算符来排序
    sort(buf.rbegin(), buf.rend());
    for (const auto &temp_buf : buf)
    {
        cout << temp_buf << " ";
    }
    cout << endl;


    /*字符比较----------------------------------------------------------------------------*/
    string str1 = "and", str2 = "egg";
    cout << (str1 > str2 ? str1 : str2) << endl;





    return 0;
}

猜你喜欢

转载自blog.csdn.net/ksmtnsv37297/article/details/89349235
今日推荐