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)

1.vector(向量)连续存储的元素。直接访问任意元素,快速插入、删除尾部元素。<vector>
2.双端队列(deque) 连续存储的指向不同元素的指针所组成的数组。直接访问任意元素,快速插入、删除头部和尾部元素。<deque>
3.列表(list) 由节点组成的双向链表,每个结点包含着一个元素。快速插入、删除任意位置元素。<list>
 
顺序容器的共同函数
函数 描述
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

 
容器适配器(Container Adapters)

  Features:
    ①由顺序容器变化而来
    ②程序员可为适配器选择合适的顺序容器

4.栈(stack) 后进先出的值的排列 <stack>

  stack<ElementType> st;     //创建一个空栈st

  st.push(ElementType);      //在栈顶增加元素

  st.pop();             //移除栈顶元素(不会返回栈顶元素的值)

  st.top();              //返回栈顶元素

  st.empty();           //判断栈是否为空,空则返回true

  st.size();            //返回栈中元素数目

5.队列(queue) 先进先出的值的排列 <queue>

  queue<ElementType> q;    //创建一个空队列

  q.push(ElementType);      //将一个元素置入queue中

  q.pop();             //从queue中移除一个元素(不会返回队头元素值)

  q.front();                 //返回queue内的第一个元素(也就是第一个被置入的元素)

  q.back();            //返回queue中最后一个元素(也就是最后被插入的元素)

  q.empty();           //判断队列是否为空,空则返回true

  q.size();            //返回队列中元素数目。

  注意:pop()虽然会移除下一个元素,但是并不返回它,front()和back()返回下一个元素但并不移除该元素。

6.优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 <queue>

  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

关联式容器(Associative Containers)

  Features:
    ①使用“key”快速存取元素
    ②元素按规则排序
    ③默认用< 运算符排序

7.集合(set) 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 。快速查询元素,无重复关键字。<set>
8.多重集合(multiset) 允许存在两个次序相等的元素的集合。与set相同,但允许重复关键字<set>
9.映射(map) 由{键,值}对组成的集合,以某种作用于键对上的谓词排列。Key/value pair mapping(键值对映射)。不允许重复关键字,使用关键字快速查询元素 <map>
10.多重映射(multimap) 允许键对有相等的次序的映射。与map相同,但允许重复关键字 <map>
 
关联容器中的共同函数
函数 描述
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

上一篇:EF Repository Update


下一篇:MATLAB符号求解极限积分微分级数2