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 ...