顺序容器:容器中的元素是有顺序的,按位置存储。
关联容器:按元素的值来存储。
一、顺序容器
不同顺序容器的性能比较:
vetcor string 便于随机访问元素,list forward_list 便于增删元素。deque 在两端增删元素较快。每个容器都有一个头文件,还有默认的构造函数。#include<vector> #include<list>
1、迭代器:
begin end : 返回地址
cbegin cend :返回const类型的值
rbegin rend : 反向迭代器
2、容器的操作:
(1)定义:array<int ,10> array 容器要指定大小
顺序容器上定义的数据类型:iterator const_iterator size_type 等。如:vector<int>::iterator it1;
初始化、赋值:
swap(a,b) 交换a,b内容。
ar.assign(n) 将ar中的所有元素初始化为n。
ar.assign(n,"s") 将ar中的所有元素初始化为n个s。
ar.assign(a.cbegin,b.cend) 不同容器之间可用cbegin或cend通过assign相互赋值。
(2)size、empty、max_size
(3)关系运算 > < =
3、顺序容器的操作
(1)添加:
push_back: c.push_back(element); //向后追加元素
push_front: list、forward_list、deque 容器支持 //向前追加元素
insert: c.insert(c.begin(),"hello") c.insert(c.begin(),10,"hello") c.insert(c.end(),d.begin(),d.end())
在当前位置的前一个位置插入元素,返回新插入元素的迭代器。
emplace: emplace_back emplace_front emplace 作用同push、insert 不用之处:emplace有多个参数。
(2)访问:c.back() c.front() c[i](下标操作list容器没有) c.at(n)
(3)删除元素:c.pop_back() c.pop_front() c.erase(p) c.erase(b,e) c.clear()
erase返回下一个元素的迭代器
(4) forward_list: 由于添加或删除一个元素会导致前驱元素的改变,forward_list又是单向链表,不容易获得前驱。故forward_list添加或删除元素是通过改变其后的元素来完成的。
(5)改变容器的大小:c.resize(n,value) 如果resize小于当前的值,则缩小容器,反之,扩大容器。
(6)容器修改后,可能会使指向容器元素的指针、引用、迭代器失效。注意迭代器的位置。
向vector、string、deque中添加删除元素后,end迭代器会失效。
(7)vector、string空间分配策略:分配比需求空间更大的内存,避免每次增加元素都分配内存。
c.capacity() 返回当前容器所能容纳的元素个数。
c.size():当前容器元素的个数。
(8)string特殊操作:
拷贝任意一段字符串 substr(n) //从第n个字符开始读取
append、replace 追加、替换元素
c.find("string") 搜索元素、逆向搜索
compare: 比较字符串,6个版本
与不同的数据类型相互转换
(9)顺序容器的适配器:stack queue priority_queue
容器上建栈:stack<string,vector<string>> stk; stack<int> stk;
二、关联容器
1、8种类型:
头文件:#include<map> #include<set> #include<unordered_map> #include<unordered_set>
map:元素由“键——值”构成 set:每个元素包含一个关键字
这些容器的不同体现在三个方面:
(1)或者是set,或者是map
(2)是否有重复的关键字
(3)元素是否有序
2、容器的操作:
(1)初始化:
map<string,size_t> words; //words.first words.second
set<string> exc{"the","hope"}; // exc.find(word) 若在exc中查找到word,返回对应位置的迭代器,否则返回尾 后迭代器(exc.end())。
pair 类型,类似于map容器。pair<string,size_t> word_count; map中的每个元素都是一个pair对象
关联容器上定义的数据类型:iterator key_type mapped_type value_typed size_type
对于set来说,key_type等同于value_type
map<string,int>::key_type v1; //v1相当于string
map<string,int>::value_type v2; //v2相当于pair<conststring,int> (关键字的值不能改变)
map<string,int>::mapped_type v3; //v3相当于 int
(2)迭代器:
解引用(*it / it->):对于map解引用是pair类型的,而set是value_type 类型的
map/set :map的关键字和set的关键字是const类型的。
(3)添加、删除元素:
set : c.insert(n); map : c.insert({word,1}); c.insert(make_pair(word,1));
insert 返回值:pair<关键字,bool> 若关键字已经存在于容器中 返归 false
c.erase(关键字);
(4)map、unordered_map 有下标操作。c[关键字] 返回mapped_type对象(“值”)。若无此关键字则插入这个关键字。 c[key]=value; //若不存在此key,相当于赋值
(5)访问元素:
c.find(n);// 返回该元素的迭代器 c.count(n); //统计个数
c.lower_bound(关键字)与c.upper_bound(关键字) 构成了该关键字的一个范围。若无此关键字,则返回相等的迭代器。或直接使用 c.equal_range(关键字) 返回pair<T,T> first / second
3、无序容器:
用哈希函数来组织元素,元素通过哈希函数映射到桶。
容器中含有若干桶,桶中含若干个元素。
单词转换map:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include<fstream>
#include <string>
#include<sstream>
#include<map>
using namespace std;
map<string, string> buildmap(ifstream& is);
void trans(ifstream &a,ifstream &b);
map<string, string> buildmap(ifstream& is) //将转换规则映射到map
{
map<string, string> mrule;
string key,value;
while (is >> key&&getline(is, value))
{
if (value.size() > 1)
mrule[key] = value.substr(1);
else
throw runtime_error("no rule for"+key);
}
return mrule;
}
void trans(ifstream &a, ifstream &b)
{
auto trule = buildmap(a); //建立map转换
string line,key;
while (getline(b,line)) //读取一行
{
istringstream stream(line);
while (stream>>key) //读取这一行中的每一个单词(istringstream)
{
auto tf = trule.find(key);
if (tf != trule.end())
cout << tf->second << ' ';
else
cout << key << ' ';
}
cout << endl;
}
}
int main()
{
ifstream ifs_a;
ifstream ifs_b;
ifs_a.open("C:\\Users\\fm\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication1\\rule.txt");
if (ifs_a.is_open())
{
cout << "文件a打开" << endl;
}
ifs_b.open("C:\\Users\\fm\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication1\\trans.txt");
if (ifs_b.is_open())
{
cout << "文件b打开" << endl;
}
trans(ifs_a,ifs_b);
ifs_a.close();
ifs_b.close();
return 0;
}