所有容器的共同操作
==和!=返回true或false
= 将某个容器复制个另一个容器
empty()在容器没有任何元素时返回true
size()容器内当前含有的元素
clear() 清除所有元素
begin()返回iterator,指向容器的第一个元素
end()返回iterator,指向容器最后一个元素的下一个位置
insert() 将一个或某个范围的元素插入容器
erase() 将容器内一个或某个范围的元素删除
使用序列式容器
序列式容器维护一组排列有序同类型的元素。
vector以一块儿连续内存存放元素,对vector进行随机存取颇有效率,如果将元素插入任意位置而不是vector末尾,效率将很低,同样删除末尾之外的任意元素,效率也很低。
vector比较适合数列。
list双向链接,非连续内存存储内容,可以执行向前或后退操作。每个元素包含三个字段:value、back指针(指向前一个元素)、front指针(指向下一个元素),在任意位置进行元素的插入或删除操作都很有效率。但如果进行随机存取操作,效率就不好了。
如果从文件中读取数据并排序,则每读一个数据便可能随机插入到数列中,可以选用list。
deque与vector类似都在连续内存中存放元素,但是deque对前端和末尾插入和删除元素都很有效率。
使用序列容器必须包含的头文件
#include <vector>
#include <list>
#include <deque>
有5种方式来定义序列容器:
1、创建空容器
list<string> slist;
vector<int> ivec;
2、创建特定大小的容器,元素以默认值作为初值
list<int> ilist(1024);
vector<string> svec(32);
3、创建特定大小的容器,并为每个元素赋特定初值
vector<int> ivec(10, -1);
list<string> slist(16, "unassigned");
4、创建一个容器,用iterator区间的元素初始化容器
int ia[8] = { 1, 1, 2, 3, 5, 8, 13, 21 };
vector<int> fib(ia, ia+8);
5、依据某容器创建新容器,复制原容器的元素作为新容器的初值
list<string> slist; // empty
// fill slist ...
list<string> slist2(slist); // copy of slist ...
两个特别的操作函数:
push_back():在容器末端插入一个元素
pop_back():删除末端元素
list和deque还提供了push_front()和pop_front()
pop_back()和pop_front()不返回被删除的元素值,可以用back()和front()函数得到。
容器除了通用的insert()插入函数外,还有其它四种变形。
iterator insert(iterator position, elemType value) 将value插入position之前,返回一个迭代器指向被插入元素;
list<int> ilist;
// ... fill up ilist
list<int>::iterator it = ilist.begin();
while (it != ilist.end())
if (*it >= ival)
{
ilist.insert(it, ival);
break; // exit loop
}
if (it == ilist.end())
ilist.push_back(ival);
void insert(iterator position, int count, elemType value) 在position之前插入count个元素,每个元素的值为value
string sval("Part Two");
list<string> slist;
// ... fill slist ...
list<string>::iterator it = find(slist.begin(), slist.end(),
sval);
slist.insert(it, 8, string("dummy"));
void insert(iterator1 position, iterator2 first, iterator2 last)在position之前插入first和last之间的元素
int ia1[7] = { 1, 1, 2, 3, 5, 55, 89 };
int ia2[4] = { 8, 13, 21, 34 };
list<int> elems(ia1, ia1+7);
list<int>::iterator
it = find(elems.begin(), elems.end(), 55);
elems.insert(it, ia2, ia2 + 4);
iterator insert(iterator position)在position之前插入元素,该元素的值为其所属类型的默认值。
pop_back()和pop_front()均属于容器擦除操作,erase()有另外两种变形
iterator erase(iterator posit) 删除posit所指元素,返回删除元素的下一位置
list<string>::iterator
it = find(slist.begin(), slist.end(), str);
slist.erase(it);
iterator erase(iterator first, iterator last) 删除从start开始但不包含last的元素。
list<string>::iterator
first = slist.begin(),
last = slist.end();
// it1: first element to erase,
// it2: first element beyond elements to erase
list<string>::iterator it1 = find(first, last, str);
list<string>::iterator it2 = find(first, last, sval);
slist.erase(it1, it2);
list不支持iterator的偏移运算,因此不能写
// error: offset arithmetic is not
// supported for list class
slist.erase(it1, it1+num_tries);
使用泛型算法
使用泛型算法包含头文件
#include <algorithm>
下列四种是我们常用的泛型搜寻算法:
find()搜寻无序集合中是否存在某值,若找到返回值得iterator否则返回iterator指向末尾元素
binary_serach()用于搜寻有序集合,找到返回true,未找到返回false
count()返回值相符的个数
search()比较容器内是否存在某子序列,若存在返回指向子序列的起始处的迭代器,否则指向容器末尾
binary_serach()要求其实施对象必须经过排序,如果不确定是否排序,可以将容器复制一份
vector<int> temp(vec.size());
copy(vec.begin(), vec.end(), temp.begin());
sort(temp.begin(), temp.end());
return binary_search(temp.begin(), temp.end(), elem);
如何设计泛型算法
标准库为我们事先定义了一组function objects
Six arithmetic function objects: plus<type>, minus<type>, negate<type>,
multiplies<type>, divides<type>, modulus<type>
Six relational function objects: less<type>, less_equal<type>, greater<type>,
greater_equal<type>, equal_to<type>, not_equal_to<type>
Three logical function objects, using the &&, ||, and ! operators, respectively:
logical_and<type>, logical_or<type>, and logical_not<type>
头文件
#include <functional>
sort(vec.begin(), vec.end(), greater<int>());
使用map
map被定义为一对数值,通常key是字符串扮演索引的角色,另一个数值是value。
#include <map>
#include <string>
map<string,int> words;
输入key/value的最简单方式
words["vermeer"] = 1;
words[tword]会取出tword对应的value,如果tword不在map内,会被置于map内,其值为0,稍后出现,其值会加1.
map<string,int>::iterator it = words.begin();
for (; it != words.end(); ++it)
cout << "key: " << it->first
<< "value: " << it->second << endl;
map有一个名为first的成员,对应于key,second对应value。
欲查询map内是否存在key,有三种方法:
第一种:
int count = 0;
if (!(count = words[ "vermeer"]))
// vermeer not present
缺点如果搜寻的key不存在于map内,则会将其加入map
第二种:利用map的find()函数
如果含有key,怎会返回iterator指向key/value形成的pair,反之返回end();
int count = 0;
map<string,int>::iterator it;
it = words.find("vermeer");
if (it != words.end())
count = it->second;
第三种利用map的count()函数,返回key在map中个数
int count = 0;
string search_word("vermeer");
if (words.count(search_word)) // ok: present ...
count = words[search_word];
任何一个key在map中只存储一份
使用set
set由一群keys组成,如果要判断某值是否存在于集合内可以用set
#include <set>
#include <string>
set<string> word_exclusion;
while (cin >> tword)
{
if (word_exclusion.count(tword))
// present in the set of excluded words?
// then skip the rest of this iteration
continue;
// ok: if here, not an excluded word
words[tword]++;
}
使用迭代器插入
如果先定义容器大小,可能会浪费空间,我们可以先定义个空容器,当有元素插入时再扩展。
对元素进行复制的泛型算法有 copy(), copy_backwards(), remove_copy(), replace_copy(), unique_copy()
标准程序库为我们提供了3个insertion adapters
back_inserter()
vector<int> result_vec;
unique_copy(ivec.begin(), ivec.end(),
back_inserter(result_vec));
inserter()
vector<string> svec_res;
unique_copy(svec.begin(), svec.end(),inserter(svec_res, svec_res.end()));
front_inserter()
list<int> ilist_clone;
copy(ilist.begin(), ilist.end(),
front_inserter(ilist_clone));
需包含的头文件是#include <iterator>
Using the iostream Iterators
标准程序库提供输入及输出用的iostream iterator 类, istream_iterator and ostream_iterator
需包含的头文件#include <iterator>
istream_iterator<string> is(cin);
istream_iterator<string> eof;
copy(is, eof, back_inserter(text));
ostream_iterator<string> os(cout, " ");
copy(text.begin(), text.end(), os);
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
istream_iterator<string> is(cin);
istream_iterator<string> eof;
vector<string> text;
copy(is, eof, back_inserter(text));
sort(text.begin(), text.end());
ostream_iterator<string> os(cout, " ");
copy(text.begin(), text.end(), os);
}
对文件操作类似
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
ifstream in_file("as_you_like_it.txt");
ofstream out_file("as_you_like_it_sorted.txt");
if (! in_file || ! out_file)
{
cerr << "!!unable to open the necessary files.\n";
return -1;
}
istream_iterator<string> is(in_file);
istream_iterator<string> eof;
vector<string> text;
copy(is, eof, back_inserter(text));
sort(text.begin(), text.end());
ostream_iterator<string> os(out_file, " ");
copy(text.begin(), text.end(), os);
}