C++容器

一、容器

1.1 容器的相关概念(掌握)

泛型编程是一种编程理念,其提出的动机是发明一种语言机制,能够在编程中编写完全一般化的可重复使用的算法,不会因为数据类型的不同而有差异。

美国的惠普实验室针对泛型编程开发了一系列软件工具,被称为标准模板库(STL),后续在C++中被广泛引入。STL中绝大多数的类型都使用了模板的编程技术,这相比传统的代码而言有更好重用特性。

在STL中最核心的内容是容器和迭代器。

容器指的是用来存储数据的集合,由于内部存储的数据使用模板实现,因此可以支持绝大多数数据类型。迭代器是配合容器进行高效遍历的工具,是一种特殊的指针。

容器类自动申请和释放内存,无需new和delete操作。

容器的分类如下:

容器类的使用需要引入头文件,所有的容器类都是属于std名字空间。

1.2 顺序容器

顺序容器是一种各元素之间有顺序关系的结构集合,每个元素在容器都有固定的位置,但是可以用删除或插入等操作改变这个位置。

1.2.1 array 数组(熟悉)

array是C++ 11中引入的容器类型,与传统数组相比,array更加安全和易于使用。

#include <iostream>#include <array> // 引入头文件using namespace std;int main(){    // 创建一个长度为5的int数组    array<int,5> arr = {2,4,6,8,10};    cout << arr[0] << endl; // 2    cout << arr[4] << endl; // 10    arr[1] = 666;    cout << arr.at(1) << endl; // 666    // 普通循环    for(int i=0;i<arr.size();i++)    {        cout << arr.at(i) << " ";    }    cout << endl;    // 给所有元素赋值    arr.fill(5);    // for-each循环    for(int i:arr)    {        cout << i << " ";    }    cout << endl;    // 迭代器:略    return 0;}

1.2.2 vector 向量(掌握)

vector内部由数组实现,因此可以高效地进行元素的随机存取,但是插入和删除的效率较低,是最常用的一种顺序容器。

#include <iostream>#include <vector> // 引入头文件using namespace std;int main(){    // 创建一个长度为0的向量对象    vector<int> vec1;    cout << vec1.empty() << endl; // 1    // 创建一个长度为5的向量对象    vector<int> vec2(5);    vec2[0] = 123; // 修改元素    cout << vec2[0] << endl; // 123    cout << vec2.at(4) << endl; // 0    // 5个666    vector<int> vec3(5,666);    // 向后追加元素    vec3.push_back(888);    // 在第二个位置插入2    // 参数1:插入的位置    // 参数2:插入的元素    vec3.insert(vec3.begin()+1,2);    // 在倒数第二个位置插入222    vec3.insert(vec3.end()-1,222);    // 删除第一个元素    vec3.erase(vec3.begin());    // 删除最后一个元素    vec3.erase(vec3.end()-1);    vec3.pop_back(); // 删除最后一个元素    // 普通循环遍历    for(int i=0;i<vec3.size();i++)    {        cout << vec3.at(i) << " ";    }    cout << endl;    // 清空    vec3.clear();    // for-each遍历    for(int i:vec3)    {        cout << i << " ";    }    cout << endl;    // 迭代器遍历:略    return 0;}

1.2.3 list 列表(掌握)

list内部由双向链表实现,因此元素的内存空间是不连续的,能高效地进行插入和删除操作,但是随机存取的效率较低,并且list只能通过迭代器指针来访问数据。

#include <iostream>#include <list> // 引入头文件using namespace std;int main(){    // 创建一个四个hello元素的列表对象    list<string> lis1(4,"hello");    list<string> lis2;    // 判断是否为空    cout << lis2.empty() << endl;    // 向后追加元素    lis1.push_back("bye");    // 向前追加元素    lis1.push_front("start");    // 取出头部元素    cout << lis1.front() << endl;    // 取出尾部元素    cout << lis1.back() << endl;    // 删除头部元素    lis1.pop_front();    // 删除尾部元素    lis1.pop_back();    // 在第二个位置插入元素"2B"    lis1.insert(++lis1.begin(),"2B");    // 在倒数第二个位置插入元素"2Y"    lis1.insert(--lis1.end(),"2Y");    // 保存迭代器指针    list<string>::iterator iter = lis1.begin();    // 修改第一个元素    *iter = "One";    // 取出元素    cout << *iter << endl;    // 移动迭代器指针    // 参数1:要移动的迭代器指针对象    // 参数2:移动的距离    advance(iter,3);    // 在第四个元素的位置插入"4544"    lis1.insert(iter,"4544");    // 删除倒数第一个元素    lis1.erase(--lis1.end());    // 清空//    lis1.clear();    // 排序    lis1.sort();    // 不支持普通的for循环遍历,但是支持for-each遍历    for(string s:lis1)        cout << s << " ";    cout << endl;    // 迭代器遍历:略    return 0;}

1.2.4 deque 队列(熟悉)

deque的性能位于vector和list之间,是一种性能均衡的容器。另外,deque基本支持所有的常用API接口。

示例代码:略

1.3 关联容器(掌握)

关联容器的各元素之间没有严格的物理上顺序关系,但是内部有排序,因此可以使用迭代器遍历。

关联容器内部的元素数据以键值对(key-value pair)的形式存在。

map与multimap的区别在于,前者是单重键值对映射(一一映射),后者允许一个键对应多个值,map更为常用。

键必须唯一,通常使用字符串类型;值可以重复,可以是任何类型。

#include <iostream>#include <map> // 引入头文件using namespace std;int main(){    // 创建一个内容为空的map对象    map<string,int> map1;    // 添加元素    map1["height"] = 180;    map1.insert(pair<string,int>("country",86));    map1["salary"] = 10000;    map1["age"] = 40;    map1["weight"] = 71;    // 已经存在这个键值对,因此再次赋值就是修改键对应的值    map1["weight"] = 70;    // 删除元素    if(map1.erase("salary"))    {        cout << "删除成功,还剩下" << map1.size() << "个键值对" << endl;    }else    {        cout << "删除失败!" << endl;    }    // 迭代器指针    // 如果有对应的键,则指向键值对    // 如果没有对应的键,则执指向“最后一个元素”的后面    map<string,int>::iterator iter =  map1.find("salary");    if(iter != map1.end())    {        // 取出元素        int value = iter->second;        cout << value << endl;    }else    {        cout << "没有对应的值!" << endl;    }    // 清空    map1.clear();    cout << map1.empty() << endl;    return 0;}

1.4 迭代器(掌握)

容器的遍历通常是迭代器进行,因为迭代器对容器遍历的兼容性最好,且遍历效率最高。迭代器是一种特殊的指针,如果要使用迭代器进行读写操作,可以使用iterator类型的迭代器;如果要使用迭代器进行只读操作,可以使用const_iterator类型的迭代器,因为只读迭代器的效率更高。

#include <iostream>#include <array>#include <vector>#include <list>#include <deque>#include <map>using namespace std;int main(){    string str = "ABC678%^";    // string的只读迭代器    for(string::const_iterator iter = str.begin();iter != str.end();iter++)    {        cout << *iter << " ";    }    cout << endl;    array<double,20> arr;    arr.fill(3.14);    // array的读写迭代器    for(array<double,20>::iterator iter = arr.begin();        iter!=arr.end();iter++)    {        cout << ++(*iter) << " ";    }    cout << endl;    vector<int> vec1(4,4);    // vector的只读迭代器    vector<int>::const_iterator iter_vec = vec1.begin();    while(iter_vec != vec1.end())    {        cout << *iter_vec << " ";        iter_vec++;    }    cout << endl;    list<string> lis1;    lis1.push_back("fhdjks");    lis1.push_back("fhfggks");    lis1.push_back("dsdsghs");    lis1.push_back("fh***");    // list的读写迭代器    list<string>::iterator iter_lis = lis1.begin();    while(iter_lis != lis1.end())    {        cout << (*iter_lis).append("~") << " ";        iter_lis++;    }    cout << endl;    deque<int> deq(5,5);    // deque的读写迭代器,也可以只读    for(deque<int>::iterator iter = deq.begin();        iter!=deq.end();iter++)    {        cout << *iter << " ";    }    cout << endl;    map<string,string> map1;    map1["城市"] = "济南";    map1["name"] = "Tom";    map1["age"] = "7";    map1["friend"] = "Jerry";    // map的只读迭代器    for(map<string,string>::const_iterator iter = map1.begin();        iter != map1.end();iter++)    {        cout << iter->first << "-"; // 键        cout << iter->second << endl; // 值    }    return 0;}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值