STL之容器基本操作
STL Container | Header | Applications |
vector | <vector> | 直接访问任意元素,快速插入、删除尾部元素 |
deque | <deque> | 直接访问任意元素,快速插入、删除头部和尾部元素 |
list | <list> | 快速插入、删除任意位置元素 |
set | <set> | 快速查询元素,无重复关键字 |
multiset | <set> | 与set相同,但允许重复关键字 |
map | <map> | Key/value pair mapping(键值对映射)。不允许重复关键字,使用关键字快速查询元素 |
multimap | <map> | 与map相同,但允许重复关键字 |
stack | <stack> | 后进先出容器. |
queue | <queue> | 先进先出容器 |
priority_queue | <queue> | 高优先级元素先删除 |
Functions | Description |
non-argconstructor 无参构造函数 | 构造一个空容器 |
constructor with args带参构造函数 | 每个容器都有多个带有参数的构造函数 |
copy constructor 拷贝构造函数 | 创建一个容器,从一个已有的同类型容器中复制元素 |
destructor 析构函数 | 容器销毁后执行清理工作 |
empty() | 若容器中没有元素则返回空 |
size() | 返回容器中的元素数目 |
operator= | 将容器内容复制到另一个容器 |
Relational operators(<, <=, >, >=, ==, and !=) | 顺序比较两个容器中的对应元素,来确定大小关系 |
顺序容器+关联容器= 一级容器 | ||
Functions | Description | |
c1.swap(c2) | 交换两个容器c1和c2的内容 | |
c1.max_size() | 返回一个容器可以容纳的最大元素数量 | |
c.clear() | 删除容器中的所有元素 | |
c.begin() | 返回容器首元素的迭代器 | |
c.end() | 返回容器尾元素之后位置的迭代器 | |
c.rbegin() | 返回容器为元素的迭代器,用于逆序遍历 | |
c.rend() | 返回容器首元素之前位置的迭代器,用于逆序遍历 | |
c.erase(beg, end) | 删除容器中从beg到end-1之间的元素。beg和end都是迭代器 |
顺序容器(Sequence Container)
函数 | 描述 |
assign(n, elem) | 将指定元素elem的n份拷贝加入(赋值)到容器中 |
assign(begin, end) | 将迭代器[beg,end)间的元素赋值给当前容器 |
push_back(elem) | 将元素附加到容器 |
pop_back() | 删除容器尾元素 |
front | 返回容器首元素 |
back() | 返回容器尾元素 |
insert(position, elem) | 将元素插入到容器指定位置 |
- #include <iostream>
- #include <vector>
- using namespace std;
- int main()
- {
- double values[] = {, , , , , , };
- // 构造向量,用迭代器[beg, end)间的元素初始化向量
- vector<double> doubleVector(values, values + );
- cout << "Initial contents in doubleVector: ";
- for (int i = ; i < doubleVector.size(); i++)
- cout << doubleVector[i] << " ";
- // 顺序容器:assign(n, elem) 将n份元素拷贝赋值给容器
- doubleVector.assign(, 11.5);
- cout << "\nAfter the assign function, doubleVector: ";
- for (int i = ; i < doubleVector.size(); i++)
- cout << doubleVector[i] << " ";
- // vector/deque中特有的函数at(index)返回指定位置的元素
- doubleVector.at() = 22.4;
- cout << "\nAfter the at function, doubleVector: ";
- for (int i = ; i < doubleVector.size(); i++)
- cout << doubleVector[i] << " ";
- // 定义迭代器,令其指向向量首位置
- vector<double>::iterator itr = doubleVector.begin();
- // 顺序容器:insert(position, elem) 将元素插入指定位置
- doubleVector.insert(itr + , );
- // !!!警告!!! 调用vector的insert之后,所有的迭代器都【可能】失效!
- // doubleVector.insert(itr + 1, 666); // itr可能会失效
- itr = doubleVector.begin();
- doubleVector.insert(itr + , );
- cout << "\nAfter the insert function, doubleVector: ";
- for (int i = ; i < doubleVector.size(); i++)
- cout << doubleVector[i] << " ";
- // 一级容器: erase[beg, end) 删除指定迭代器范围的元素
- doubleVector.erase(itr + , itr + );
- //!!!警告!!! 调用vector的erase之后,beg及之后的迭代器都会失效!
- cout << "\nAfter the erase function, doubleVector: ";
- for (int i = ; i < doubleVector.size(); i++)
- cout << doubleVector[i] << " ";
- doubleVector.clear();
- cout << "\nSize is " << doubleVector.size() << endl;
- cout << "Is empty? " <<
- (doubleVector.empty() ? "true" : "false") << endl;
- return ;
- }
VectorDemo
- #include <iostream>
- #include <deque>
- using namespace std;
- int main()
- {
- double values[] = {, , , , , , };
- // 构造deque,用迭代器[beg, end)间的元素初始化deque
- deque<double> doubleDeque(values, values + );
- cout << "Initial contents in doubleDeque: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- // 顺序容器:assign(n, elem) 将n份元素拷贝赋值给容器
- doubleDeque.assign(, 11.5);
- cout << "\nAfter assign: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- // deque/vector中特有:at(index)返回指定位置的元素
- doubleDeque.at() = 22.4;
- cout << "\nAfter at: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- deque<double>::iterator itr = doubleDeque.begin();
- // 顺序容器:insert(position, elem) 将元素插入指定位置
- doubleDeque.insert(itr + , );
- // doubleDeque.insert(itr + 1, 666); // Error! Unexpected Behavior
- // !!!警告!!! 调用deque的insert之后,所有的迭代器都【必然】失效!
- //
- itr = doubleDeque.begin(); // 重新获得迭代器
- doubleDeque.insert(itr + , );
- cout << "\nAfter insert: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- // 一级容器:erase[beg, end) 删除指定迭代器范围的元素
- doubleDeque.erase(itr + , itr + );
- // !!!警告!!! 调用deque的erase之后,所有的迭代器都【可能】失效!
- cout << "\nAfter erase: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- doubleDeque.clear();
- cout << "\nAfter clear: ";
- cout << "Size is " << doubleDeque.size() << endl;
- cout << "Is empty? " <<
- (doubleDeque.empty() ? "true" : "false") << endl;
- // deque/list特有:push_front(elem)将元素压入队头
- doubleDeque.push_front(10.10); // 10.10
- doubleDeque.push_front(20.22); // 20.22 10.10
- doubleDeque.push_front(30.33); // 30.33 20.22 10.10
- cout << "After push_front: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- // deque/list特有:pop_front()删除队首元素
- doubleDeque.pop_front();
- // 顺序容器:pop_back()删除容器尾元素
- doubleDeque.pop_back();
- cout << "\nAfter pop: ";
- for (int i = ; i < doubleDeque.size(); i++)
- cout << doubleDeque[i] << " ";
- return ;
- }
DequeDemo
- #include <iostream>
- #include <list>
- using namespace std;
- int main()
- {
- int values[] = {, , , };
- // 构造list,用迭代器[beg, end)间的元素初始化list
- list<int> intList(values, values + );
- cout << "Initial contents in intList: ";
- list<int>::iterator p; // list的迭代器为双向迭代器
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- // 顺序容器:assign(n, elem) 将n份元素拷贝赋值给容器
- intList.assign(, );
- cout << "\nAfter assign, intList: ";
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- list<int>::iterator itr = intList.begin();
- itr++; // 迭代器指向第2个11: 11 ^11 11 11
- // 顺序容器:insert(position, elem) 将元素插入指定位置
- intList.insert(itr, ); // 11 555 ^11 11 11
- // 调用list的insert之后,迭代器不受影响,仍指向第2个11
- intList.insert(itr, ); // 11 555 666 ^11 11 11
- cout << "\nAfter insert, intList: ";
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- list<int>::iterator beg = intList.begin();
- itr++;
- // 一级容器: erase[beg, end) 删除指定迭代器范围的元素
- intList.erase(beg, itr);
- // !!!警告!!! 被删除元素的迭代器均失效,其它元素迭代器仍有效
- cout << "\nAfter erase, intList: ";
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- intList.clear();
- cout << "\nAfter clear, intList: ";
- cout << "Size is " << intList.size() << endl;
- cout << "Is empty? " <<
- (intList.empty() ? "true" : "false");
- // deque/list特有:push_front(elem)将元素插入列表首部
- intList.push_front();
- intList.push_front();
- intList.push_front();
- cout << "\nAfter push, intList: ";
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- // deque/list特有:pop_front()删除列表首元素
- intList.pop_front();
- // 顺序容器:pop_back()删除容器尾元素
- intList.pop_back();
- cout << "\nAfter pop functions, intList: ";
- for (p = intList.begin(); p != intList.end(); p++)
- cout << *p << " ";
- int values1[] = {, , , };
- list<int> list1(values1, values1 + );
- // list特有:sort() 将元素按升序排列
- list1.sort();
- cout << "\nAfter sort, list1: ";
- for (p = list1.begin(); p != list1.end(); p++)
- cout << *p << " ";
- list<int> list2(list1);
- // list特有:merge(l2) 假定当前list与list2都已排序,
- // 将list2合并至本表,list2变空
- list1.merge(list2);
- cout << "\nAfter merge, list1: ";
- for (p = list1.begin(); p != list1.end(); p++)
- cout << *p << " ";
- cout << "\nSize of list2 is " << list2.size();
- // list特有:reverse()反转本列表
- list1.reverse();
- cout << "\nAfter reverse, list1: ";
- for (p = list1.begin(); p != list1.end(); p++)
- cout << *p << " ";
- list1.push_back();
- list1.push_back();
- cout << "\nAfter push, list1: ";
- for (p = list1.begin(); p != list1.end(); p++)
- cout << *p << " ";
- // list特有:remove(elem)删除表中与elem相等的元素
- list1.remove();
- cout << "\nAfter remove, list1: ";
- for (p = list1.begin(); p != list1.end(); p++)
- cout << *p << " ";
- // 顺序容器:assign(n, elem) 将n份elem拷贝赋值给容器
- list2.assign(, );
- cout << "\nAfter assign, list2: ";
- for (p = list2.begin(); p != list2.end(); p++)
- cout << *p << " ";
- p = list2.begin();
- p++;
- // list特有:splice(pos,li)将li中所有元素移至本表pos位置之前
- // 然后li变空
- list2.splice(p, list1);
- cout << "\nAfter splice, list2: ";
- for (p = list2.begin(); p != list2.end(); p++)
- cout << *p << " ";
- cout << "\nAfter splice, list1 size: "
- << list1.size();
- return ;
- }
ListDemo
Features:
①由顺序容器变化而来
②程序员可为适配器选择合适的顺序容器
stack<ElementType> st; //创建一个空栈st
st.push(ElementType); //在栈顶增加元素
st.pop(); //移除栈顶元素(不会返回栈顶元素的值)
st.top(); //返回栈顶元素
st.empty(); //判断栈是否为空,空则返回true
st.size(); //返回栈中元素数目
queue<ElementType> q; //创建一个空队列
q.push(ElementType); //将一个元素置入queue中
q.pop(); //从queue中移除一个元素(不会返回队头元素值)
q.front(); //返回queue内的第一个元素(也就是第一个被置入的元素)
q.back(); //返回queue中最后一个元素(也就是最后被插入的元素)
q.empty(); //判断队列是否为空,空则返回true
q.size(); //返回队列中元素数目。
注意:pop()虽然会移除下一个元素,但是并不返回它,front()和back()返回下一个元素但并不移除该元素。
priority_queue<ElementType> pq; //创建一个数据越大,优先级越高的队列
priority_queue<int, vector<int>, greater<int> > pq; //创建一个数据越小,优先级越高的队列
pq.push(ElementType); //将一个元素置入priority_queue中
pq.pop(); //从priority_queue中移除一个元素(不会返回队头元素值)
pq.top(); //返回priority_queue中优先级最高的元素
pq.empty(); //判断priority_queue是否为空,空则返回true
pq.size(); //返回priority_queue中元素数目
自定义优先级,重载比较符号
重载默认的 < 符号
- struct node
- {
- friend bool operator< (node n1, node n2)
- {
- return n1.priority < n2.priority;
- }
- int priority;
- int value;
- };
这时,需要为每个元素自定义一个优先级。
注:重载>号会编译出错,因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
而且自定义类型的<操作符与>操作符并无直接联系
- #include<iostream>
- #include<functional>
- #include<queue>
- using Namespace stdnamespace std;
- struct node
- {
- friend bool operator< (node n1, node n2)
- {
- return n1.priority < n2.priority;
- }
- int priority;
- int value;
- };
- int main()
- {
- const int len = ;
- int i;
- int a[len] = {,,,,};
- //示例1
- priority_queue<int> qi;
- for(i = ; i < len; i++)
- qi.push(a[i]);
- for(i = ; i < len; i++)
- {
- cout<<qi.top()<<" ";
- qi.pop();
- }
- cout<<endl;
- //示例2
- priority_queue<int, vector<int>, greater<int> >qi2;
- for(i = ; i < len; i++)
- qi2.push(a[i]);
- for(i = ; i < len; i++)
- {
- cout<<qi2.top()<<" ";
- qi2.pop();
- }
- cout<<endl;
- //示例3
- priority_queue<node> qn;
- node b[len];
- b[].priority = ; b[].value = ;
- b[].priority = ; b[].value = ;
- b[].priority = ; b[].value = ;
- b[].priority = ; b[].value = ;
- b[].priority = ; b[].value = ;
- for(i = ; i < len; i++)
- qn.push(b[i]);
- cout<<"优先级"<<'\t'<<"值"<<endl;
- for(i = ; i < len; i++)
- {
- cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
- qn.pop();
- }
- return ;
- }
View Eg Code
优先队列(priority_queue) from:http://www.cnblogs.com/void/archive/2012/02/01/2335224.html
Features:
①使用“key”快速存取元素
②元素按规则排序
③默认用< 运算符排序
函数 | 描述 |
find(key) | 搜索容器中具有key的元素,返回指向该元素的迭代器 |
lower_bound(key) | 搜索容器中具有key的第一个元素,返回指向该元素的迭代器 |
upper_bound(key) | 搜索容器中具有key的最后一个元素,返回指向该元素之后位置的迭代器 |
count(key) | 返回容器中具有key的元素的数目 |
- #include <iostream>
- #include <set>
- using namespace std;
- int main()
- {
- int values[] = {, , , , , };
- // 构造multiset,用迭代器[beg, end)间的元素初始化deque
- // 升序排列 1,2,2,3,5,7
- multiset<int> set1(values, values + );
- // 降序排列 7,5,3,2,2,1
- // multiset<int, greater<int> > set1(values, values + 6);
- cout << "Initial contents in set1: ";
- multiset<int>::iterator p;
- for (p = set1.begin(); p != set1.end(); p++) // set支持双向迭代器
- cout << *p << " ";
- set1.insert(); // 1,2,2,3,5,7,555
- set1.insert(); // 1,1,2,2,3,5,7,555
- cout << "\nAfter insert, set1: ";
- for (p = set1.begin(); p != set1.end(); p++)
- cout << *p << " ";
- p = set1.lower_bound(); // p指向容器中第一个2
- cout << "\nValue of Lower bound of 2: " << *p;
- p = set1.upper_bound(); // p指向容器中最后一个2的后面
- cout << "\nValue of Upper bound of 2: " << *p;
- p = set1.find();
- if (p == set1.end()) // 若迭代器指向set尾部,则未找到
- cout << "2 is not in set1" << endl;
- else
- cout << "\nThe number of 2: " << set1.count();
- set1.erase(); // 将所有值为2的元素都删掉
- cout << "\nAfter erase, set1: ";
- for (p = set1.begin(); p != set1.end(); p++)
- cout << *p << " ";
- return ;
- }
SetDemo
- #include <iostream>
- #include <map>
- #include <string>
- using namespace std;
- int main()
- {
- map<int, string> map1;
- // 插入键值对
- map1.insert(map<int, string>::value_type(, "Zhang San"));
- map1.insert(map<int, string>::value_type(, "Li Si"));
- map1.insert(map<int, string>::value_type(, "Zhen Xiaosa"));
- map1.insert(map<int, string>::value_type(, "Hao Meili"));
- cout << "Initial contents in map1:\n";
- map<int, string>::iterator p;
- for (p = map1.begin(); p != map1.end(); p++)
- cout << p->first << " " << p->second << endl;
- // 使用 first 访问 key; 使用 second 访问 value
- cout << "Enter a key to serach for the name: ";
- int key;
- cin >> key;
- p = map1.find(key);
- if (p == map1.end()) // 若迭代器指向map尾部,则未找到指定键
- cout << " Key " << key << " not found in map1";
- else
- cout << " " << p->first << " " << p->second << endl;
- map1.erase();
- cout << "\nAfter erase 103, map1:\n";
- for (p = map1.begin(); p != map1.end(); p++)
- cout << p->first << " " << p->second << endl;
- return ;
- }
MapDemo
STL之容器基本操作的更多相关文章
- 详解C++ STL map 容器
详解C++ STL map 容器 本篇随笔简单讲解一下\(C++STL\)中的\(map\)容器的使用方法和使用技巧. map容器的概念 \(map\)的英语释义是"地图",但\( ...
- C++ STL vector容器学习
STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...
- STL List容器
转载http://www.cnblogs.com/fangyukuan/archive/2010/09/21/1832364.html 各个容器有很多的相似性.先学好一个,其它的就好办了.先从基础开始 ...
- STL之容器适配器queue的实现框架
说明:本文仅供学习交流,转载请标明出处,欢迎转载! 上篇文章STL之容器适配器stack的实现框架已经介绍了STL是怎样借助基础容器实现一种经常使用的数据结构stack (栈),本文介绍下第二种STL ...
- STL的容器算法迭代器的设计理念
1) STL的容器通过类模板技术,实现数据类型和容器模型的分离. 2) STL的迭代器技术实现了遍历容器的统一方法:也为STL的算法提供了统一性. 3) STL的函数对象实现了自定义数据类型的算法运算 ...
- c++复习:STL之容器
1 STL的string 1 String概念 string是STL的字符串类型,通常用来表示字符串.而在使用string之前,字符串通常是用char*表示的.string与char*都可以用来表示字 ...
- stl之容器、迭代器、算法几者之间的关系
转自:https://blog.csdn.net/bobodem/article/details/49386131 stl包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的优 ...
- STL Queue 容器
STL Queue 容器 Queue简介 queue是队列容器,是一种“先进先出”的容器. queue是简单地装饰deque容器而成为另外的一种容器. # ...
- STL stack 容器
STL stack 容器 Stack简介 stack是堆栈容器,是一种“先进后出”的容器. stack是简单地装饰deque容器而成为另外的一种容器. #include <s ...
随机推荐
- Integer cache
View.findViewById采用深度遍历,找到第一个匹配的控件 Integer Cache public static void testIntegerCache() { Class cache ...
- 转载:Cocos2D-x 游戏接入 Windows 设备所需做的六件事
原文地址:http://msopentech.com/zh-hans/blog/2014/05/09/cocos2d-x-%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%85%A5-wi ...
- Xml语言
一.XML是什么?作用是什么? l XML ( eXtensible Markup Language )语言是一种可扩展的标记语言.其中的可扩展是相对HTML来说的.因为XML标签没有被预定义,需要 ...
- Node.js log4js日志记录
这次需要给之前弄的文件服务器添加日志记录,一般每天产生的日志会特别多所以安装日期来划分是最好的,这里我用了express框架,为了适应express框架这里在log.js文件中写了use方法. //日 ...
- Flex 使用列表和表格
Flex 设计了不同的控件来实现列表和表格,不仅能够将数据显示在表格和列表中,还可以实现对数据进行操纵,修改等更加强大的功能. 与列表和表格相关的控件如下所示: 列表控件(List Control): ...
- 慕课网-安卓工程师初养成-2-1 Java中的关键字
来源:http://www.imooc.com/code/1176 Java 中常用关键字: 问:这么多,记不住啊......-_-|| 答:现在不需要你记住所有,混个眼熟即可,在学习的过程中,你会逐 ...
- IE SEESION共享的问题
前几天,我们在开发工作流的过程中出现了一个比较奇怪的问题,原本看不到流程的人员,在登陆后却能够看到对应流程的待办任务,并且导致流程流向混乱!在调模式下调试程序发现(假设登陆两个用户)第二个登陆用户的信 ...
- 华为OJ平台——整形数组合并
题目描述: 将两个整型数组按照升序合并,并且过滤掉重复数组元素 输入: 输入说明,按下列顺序输入: 1 输入第一个数组的个数 2 输入第一个数组的数值 3 输入第二个数组的个数 4 输入第二个数组的数 ...
- c#中如何做日期的三元判断(日期不为空赋值)
<dx:ASPxDateEdit runat="server" ID="edTab4_protocoldate" Width="100%&quo ...
- 在Tomcat下部属项目三种方式:
在Tomcat下部属项目三种方式: 1直接复制: 2. 通过配置虚拟路径的方式 直接修改配置文件 写到tomcat/conf/server.xml 找到<H ...