常用STL库的整理
1、vector
1. 在C++中的详细说明
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,
简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
2. 使用vector,
必须在你的头文件中包含下面的代码:
#include
vector属于std命名域的,因此需要通过命名限定,如下完成你的代码:
using std::vector;
vector vInts;
或者连在一起,使用全名:
std::vector vInts;
建议使用全局的命名域方式:
using namespace std;
3. 初始化
vector
vector c1(c2)
vector c(n)
vector c(n, elem)
vector c(beg,end)
4. 析构函数
c.~vector ()
5. 成员函数
c.assign(beg,end)c.assign(n,elem)
将[beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。
c.at(idx)
传回索引idx所指的数据,如果idx越界,抛出out_of_range。
c.back()
c.begin()
c.capacity()
c.clear()
c.empty()
c.end()
c.erase(pos)
c.erase(beg,end)
c.front()
get_allocator
c.insert(pos,elem)
c.insert(pos,n,elem)
c.insert(pos,beg,end)
c.max_size()
c.pop_back()
c.push_back(elem)
c.rbegin()
c.rend()
c.resize(num)
c.reserve()
c.size()
c1.swap(c2)
swap(c1,c2)
operator[]
6. 用法示例:
6.1. 创建一个vector
vector容器提供了多种创建方法,下面介绍几种常用的。
创建一个Widget类型的空的vector对象:
vector vWidgets;
创建一个包含500个Widget类型数据的vector:
vector vWidgets(500);
创建一个包含500个Widget类型数据的vector,并且都初始化为0:
vector vWidgets(500, Widget(0));
创建一个Widget的拷贝:
vector vWidgetsFromAnother(vWidgets);
向vector添加一个数据
vector添加数据的缺省方法是push_back()。
push_back()函数表示将数据添加到vector的尾部,并按需要来分配内存。
例如:向vector中添加10个数据,需要如下编写代码:
for(int i= 0;i<10; i++) {
vWidgets.push_back(Widget(i));
}
6.2 获取vector中指定位置的数据
vector里面的数据是动态分配的,使用push_back()的一系列分配空间常常决定于文件或一些数据源。
如果想知道vector存放了多少数据,可以使用empty()。
获取vector的大小,可以使用size()。
例如,如果想获取一个vector v的大小,但不知道它是否为空,或者已经包含了数据,如果为空想设置为-1,
你可以使用下面的代码实现:
int nSize = v.empty() ? -1 : static_cast(v.size());
6.3 访问vector中的数据
使用两种方法来访问vector。
1、 vector::at()
2、 vector::operator[]
operator[]主要是为了与C语言进行兼容。它可以像C语言数组一样操作。
但at()是我们的首选,因为at()进行了边界检查,如果访问超过了vector的范围,将抛出一个例外。
由于operator[]容易造成一些错误,所有我们很少用它,下面进行验证一下:
分析下面的代码:
vector v;
v.reserve(10);
for(int i=0; i<7; i++) {
v.push_back(i);
}
try {int iVal1 = v[7];
int iVal2 = v.at(7);
}
catch(const exception& e) {
cout << e.what();
}
6.3 删除vector中的数据
vector能够非常容易地添加数据,也能很方便地取出数据,
同样vector提供了erase(),pop_back(),clear()来删除数据,
当删除数据时,应该知道要删除尾部的数据,或者是删除所有数据,还是个别的数据。
Remove_if()算法 如果要使用remove_if(),需要在头文件中包含如下代码::
#include
Remove_if()有三个参数:
1、 iterator _First:指向第一个数据的迭代指针。
2、 iterator _Last:指向最后一个数据的迭代指针。
3、 predicate _Pred:一个可以对迭代操作的条件函数。
6.4 条件函数
条件函数是一个按照用户定义的条件返回是或否的结果,是最基本的函数指针,或是一个函数对象。
这个函数对象需要支持所有的函数调用操作,重载operator()()操作。
remove_if()是通过unary_function继承下来的,允许传递数据作为条件。
例如,假如想从一个vector中删除匹配的数据,如果字串中包含了一个值,从这个值开始,从这个值结束。
首先应该建立一个数据结构来包含这些数据,类似代码如下:
#include
enum findmodes {
FM_INVALID = 0,
FM_IS,
FM_STARTSWITH,
FM_ENDSWITH,
FM_CONTAINS
};
typedef struct tagFindStr {
UINT iMode;
CString szMatchStr;
} FindStr;
typedef FindStr* LPFINDSTR;
然后处理条件判断:
class FindMatchingString : public std::unary_function {
public:
FindMatchingString(const LPFINDSTR lpFS) :
m_lpFS(lpFS) {}
bool operator()(CString& szStringToCompare) const {
bool retVal = false;
switch (m_lpFS->iMode) {
case FM_IS: {
retVal = (szStringToCompare == m_lpFDD->szMatchStr);
break;
}
case FM_STARTSWITH: {
retVal = (szStringToCompare.Left(m_lpFDD->szMatchStr.GetLength())
== m_lpFDD->szWindowTitle);
break;
}
case FM_ENDSWITH: {
retVal = (szStringToCompare.Right(m_lpFDD->szMatchStr.GetLength())
== m_lpFDD->szMatchStr);
break;
}
case FM_CONTAINS: {
retVal = (szStringToCompare.Find(m_lpFDD->szMatchStr) != -1);
break;
}
}
return retVal;
}
private:
LPFINDSTR m_lpFS;
};
通过这个操作你可以从vector中有效地删除数据:
FindStr fs;
fs.iMode = FM_CONTAINS;
fs.szMatchStr = szRemove;
vs.erase(std::remove_if(vs.begin(), vs.end(), FindMatchingString(&fs)), vs.end());
Remove(),remove_if()等所有的移出操作都是建立在一个迭代范围上的,不能操作容器中的数据。
所以在使用remove_if(),实际上操作的时容器里数据的上面的。
看到remove_if()实际上是根据条件对迭代地址进行了修改,在数据的后面存在一些残余的数据,
那些需要删除的数据。剩下的数据的位置可能不是原来的数据,但他们是不知道的。
调用erase()来删除那些残余的数据。
注意上面例子中通过erase()删除remove_if()的结果和vs.enc()范围的数据。
7. 综合例子:
#include
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#include
#include
using namespace std;
struct STResult
{
double Time;
double Xp;
double Yp;
int id;
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
vector ResultVector;
void __fastcall test()
{
STResult stritem;
stritem.Time = .1;
stritem.Xp = .1;
stritem.Yp = .1;
stritem.id = 1;
ResultVector.push_back( stritem );
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
test();
assert(ResultVector[0].id == 1);
}
2、string
#include
using std::string;
using std::wstring;
或
using namespace std;
下面你就可以使用string/wstring了,它们两分别对应着char和wchar_t。
string和wstring的用法是一样的,以下只用string作介绍:
string类的构造函数:
string(const char *s);
string(int n,char c);
此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常 ;
string类的字符操作:
const char &operator[](int n)const;
const char &at(int n)const;
char &operator[](int n);
char &at(int n);
operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
const char *data()const;
const char *c_str()const;
int copy(char *s, int n, int pos = 0) const;
string的特性描述:
int capacity()const;
int max_size()const;
int size()const;
int length()const;
bool empty()const;
void resize(int len,char c);
string类的输入输出操作:
string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。
函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。
string的赋值:
string &operator=(const string &s);
string &assign(const char *s);
string &assign(const char *s,int n);
string &assign(const string &s);
string &assign(int n,char c);
string &assign(const string &s,int start,int n);
string &assign(const_iterator first,const_itertor last);
string的连接:
string &operator+=(const string &s);
string &append(const char *s);
string &append(const char *s,int n);
string &append(const string &s);
string &append(const string &s,int pos,int n);
string &append(int n,char c);
string &append(const_iterator first,const_iterator last);
string的比较:
bool operator==(const string &s1,const string &s2)const;
运算符">","<",">=","<=","!="均被重载用于字符串的比较;
int compare(const string &s) const;
int compare(int pos, int n,const string &s)const;
int compare(int pos, int n,const string &s,int pos2,int n2)const;
int compare(const char *s) const;
int compare(int pos, int n,const char *s) const;
int compare(int pos, int n,const char *s, int pos2) const;
compare函数在>时返回1,<时返回-1,==时返回0
string的子串:
string substr(int pos = 0,int n = npos) const;
string的交换:
void swap(string &s2);
string类的查找函数:
int find(char c, int pos = 0) const;
int find(const char *s, int pos = 0) const;
int find(const char *s, int pos, int n) const;
int find(const string &s, int pos = 0) const;
int rfind(char c, int pos = npos) const;
int rfind(const char *s, int pos = npos) const;
int rfind(const char *s, int pos, int n = npos) const;
int rfind(const string &s,int pos = npos) const;
int find_first_of(char c, int pos = 0) const;
int find_first_of(const char *s, int pos = 0) const;
int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;
int find_first_not_of(char c, int pos = 0) const;
int find_first_not_of(const char *s, int pos = 0) const;
int find_first_not_of(const char *s, int pos,int n) const;
int find_first_not_of(const string &s,int pos = 0) const;
int find_last_of(char c, int pos = npos) const;
int find_last_of(const char *s, int pos = npos) const;
int find_last_of(const char *s, int pos, int n = npos) const;
int find_last_of(const string &s,int pos = npos) const;
int find_last_not_of(char c, int pos = npos) const;
int find_last_not_of(const char *s, int pos = npos) const;
int find_last_not_of(const char *s, int pos, int n) const;
int find_last_not_of(const string &s,int pos = npos) const;
string &replace(int p0, int n0,const char *s);
string &replace(int p0, int n0,const char *s, int n);
string &replace(int p0, int n0,const string &s);
string &replace(int p0, int n0,const string &s, int pos, int n);
string &replace(int p0, int n0,int n, char c);
string &replace(iterator first0, iterator last0,const char *s);
string &replace(iterator first0, iterator last0,const char *s, int n);
string &replace(iterator first0, iterator last0,const string &s);
string &replace(iterator first0, iterator last0,int n, char c);
string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);
string类的插入函数:
string &insert(int p0, const char *s);
string &insert(int p0, const char *s, int n);
string &insert(int p0,const string &s);
string &insert(int p0,const string &s, int pos, int n);
string &insert(int p0, int n, char c);
iterator insert(iterator it, char c);
void insert(iterator it, const_iterator first, const_iterator last);
void insert(iterator it, int n, char c);
string类的删除函数
iterator erase(iterator first, iterator last);
iterator erase(iterator it);
string &erase(int pos = 0, int n = npos);
string类的迭代器处理:
string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。
用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
const_iterator begin()const;
iterator begin();
const_iterator end()const;
iterator end();
const_iterator rbegin()const;
iterator rbegin();
const_iterator rend()const;
iterator rend();
rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现
字符串流处理:
通过定义ostringstream和istringstream变量实现,#include 头文件中
例如:
string input("hello,this is a test");
istringstream is(input);
string s1,s2,s3,s4;
is>>s1>>s2>>s3>>s4;
ostringstream os;
os<cout<
3、sstream
1、头文件
[cpp] view plaincopyprint?
#include
2、作用
istringstream类用于执行C++风格的字符串流的输入操作。
ostringstream类用于执行C++风格的字符串流的输出操作。
strstream类同时可以支持C++风格的串流的输入输出操作。
3、具体分析
istringstream类
描述:从流中提取数据,支持 >> 操作
这里字符串可以包括多个单词,单词之间使用空格分开
istringstream的构造函数原形:
istringstream::istringstream(string str);
初始化:使用字符串进行初始化
istringstream istr("1 56.7");
istr.str("1 56.7");
使用:我们可以使用分解点获取不同的数据,完成 字符串 到 其他类型 的转换
常用成员函数:
str():使istringstream对象返回一个string字符串
举例:把字符串类型的数据转换为其他类型
#include
#include
using namespace std;
int main()
{
istringstream istr("1 56.7");
cout<
4、set
1. 常用函数
1) 构造函数和析构函数
set c:创建空集合,不包含任何元素
set c(op):以op为排序准则,产生一个空的set
set c1(c2):复制c2中的元素到c1中
set c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合
set c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。
c.~set()销毁所有元素,释放内存
multiset mc:创建空集合,不包含任何元素
multiset mc(op):以op为排序准则,产生一个空的set
multiset c1(c2):复制c2中的元素到c1中
multiset c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合
multiset c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。
c.~set()销毁所有元素,释放内存
[cpp] view plaincopy
#include
#include
bool fncomp (int lhs, int rhs) {return lhsstruct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhsint main ()
{
std::set<int> first;
int myints[]= {10,20,30,40,50};
std::set<int> second (myints,myints+5);
std::set<int> third (second);
std::set<int> fourth (second.begin(), second.end());
std::set<int,classcomp> fifth;
bool(*fn_pt)(int,int) = fncomp;
std::set<int,bool(*)(int,int)> sixth (fn_pt);
return 0;
}
2) 大小、判断空函数
int size() const:返回容器元素个数
bool empty() const:判断容器是否为空,若返回true,表明容器已空
3) 增加、删除函数
pairbool> insert( x):插入元素x
iterator insert(iterator it,x):在迭代器it处插入元素x
void insert(const value_type *first,const value_type *last):插入[first, last)之间元素
iterator erase(iterator it):删除迭代器指针it处元素
iterator erase(iterator first,iterator last):删除[first, last)之间元素
size_type erase(const Key& key):删除元素值等于key的元素
[cpp] view plaincopy
#include
#include
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
std::pair<std::set<int>::iterator,bool> ret;
for (int i=1; i<=5; ++i) myset.insert(i*10);
ret = myset.insert(20);
if (ret.second==false) it=ret.first;
myset.insert (it,25);
myset.insert (it,24);
myset.insert (it,26);
int myints[]= {5,10,15};
myset.insert (myints,myints+3);
std::cout << "myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
[cpp] view plaincopy
#include
#include
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
for (int i=1; i<10; i++) myset.insert(i*10);
it = myset.begin();
++it;
myset.erase (it);
myset.erase (40);
it = myset.find (60);
myset.erase (it, myset.end());
std::cout << "myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
4) 遍历函数
iterator begin():返回首元素的迭代器指针
iterator end():返回尾元素的迭代器指针
reverse_iterator rbegin():返回尾元素的逆向迭代器指针
reverse_iterator rend():返回首元素前一个位置的迭代器指针
[cpp] view plaincopy
#include
#include
int main ()
{
int myints[] = {75,23,65,42,13};
std::set<int> myset (myints,myints+5);
std::cout << "myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
5) 操作函数
const_iterator lower_bound(const Key& key):返回容器中大于等于key的迭代器指针
const_iterator upper_bound(const Key& key):返回容器中大于key的迭代器指针
int count(const Key& key) const:返回容器中元素等于key的元素的个数
pair equal_range(const Key& key) const:返回容器中元素值等于key的迭代指针[first, last)
const_iterator find(const Key& key) const:查找功能,返回元素值等于key的迭代器指针
void swap(set& s):交换集合元素
void swap(multiset& s):交换多集合元素
[cpp] view plaincopy
#include
#include
int main ()
{
std::set<int> myset;
std::set<int>::iterator itlow,itup;
for (int i=1; i<10; i++) myset.insert(i*10);
itlow=myset.lower_bound (30);
itup=myset.upper_bound (60);
myset.erase(itlow,itup);
std::cout << "myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
[cpp] view plaincopy
#include "stdafx.h"
#include
#include
using namespace std;
int main ()
{
set<int> myset;
for (int i=1; i<=5; i++) myset.insert(i*10);
pair<set<int>::const_iterator,set<int>::const_iterator> ret;
ret = myset.equal_range(30);
cout << "the lower bound points to: " << *ret.first << '\n';
cout << "the upper bound points to: " << *ret.second << '\n';
return 0;
}
[cpp] view plaincopy
#include "stdafx.h"
#include
#include
using namespace std;
int main ()
{
int myints[]={12,75,10,32,20,25};
set<int> first (myints,myints+3);
set<int> second (myints+3,myints+6);
first.swap(second);
cout << "first contains:";
for (set<int>::iterator it=first.begin(); it!=first.end(); ++it)
cout << ' ' << *it;
cout << '\n';
cout << "second contains:";
for (set<int>::iterator it=second.begin(); it!=second.end(); ++it)
cout << ' ' << *it;
cout << '\n';
return 0;
}
5、map
map/multimap
使用map/multimap之前要加入头文件#include
map和multimap内部的数据结构也是平衡二叉树。
map和multimap根据元素的key自动对元素进行排序,要修改元素的key必须先删除拥有该key的元素,然后插入拥有新的key/value的元素。
常用函数
1.构造函数和析构函数
map m:创建空映射,不包含任何元素
map m(op):以op为排序准则,产生一个空的map
map m1(m2):复制c2中的元素到c1中
map m(const value_type *first, const value_type* last):复制[first, last)之间元素构成新映射
map m(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新映射。
m.~set()销毁所有元素,释放内存
multimap mm:创建空映射,不包含任何元素
multimap mm(op):以op为排序准则,产生一个空的multimap
multimap m1(m2):复制m2中的元素到m1中
multimap m(const value_type *first, const value_type* last):复制[first, last)之间元素构成新映射
multimap m(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新映射
m.~multimap()销毁所有元素,释放内存
[cpp] view plaincopy
#include "stdafx.h"
#include
#include
using namespace std;
bool fncomp (char lhs, char rhs) {return lhsstruct classcomp {
bool operator() (const char& lhs, const char& rhs) const
{return lhsint main ()
{
map<char,int> first;
first['a']=10;
first['b']=30;
first['c']=50;
first['d']=70;
map<char,int> second (first.begin(),first.end());
map<char,int> third (second);
map<char,int,classcomp> fourth;
bool(*fn_pt)(char,char) = fncomp;
map<char,int,bool(*)(char,char)> fifth (fn_pt);
return 0;
}
2.大小、判断空函数
int size() const:返回容器元素个数
bool empty() const:判断容器是否空,若返回true,表明容器已空。
3.增加删除函数
iterator insert(const value_type& x):插入元素x
iterator insert(iterator it,const value_type& x):在迭代指针it处插入元素x
void insert(const value_type *first,const value_type* last):插入[first, last)之间元素
iterator erase(iterator it):删除迭代指针it处元素
iterator erase(iterator first,iterator last):删除[first, last)之间元素
size_type erase(const Key& key):删除键值等于key的元素
[cpp] view plaincopy
#include "stdafx.h"
#include
#include
using namespace std;
int main ()
{
map<char,int> mymap;
mymap.insert(pair<char,int>('a',10));
mymap.insert(pair<char,int>('z',200));
pair<map<char,int>::iterator,bool> ret;
ret = mymap.insert(pair<char,int>('z',500));
if (ret.second == false)
{
cout<<"element 'z' already existed";
cout<<"with a value of "<second<<'\n';
}
map<char,int>::iterator it = mymap.begin();
mymap.insert(it,pair<char,int>('b',300));
mymap.insert(it,pair<char,int>('c',400));
map<char,int> anothermap;
anothermap.insert(mymap.begin(),mymap.find('c'));
cout<<"mymap contains :\n";
for (it = mymap.begin();it!= mymap.end();it++)
{
cout<first<<"=>"<second<<'\n';
}
cout<<"anothermap contains :\n";
for (it = anothermap.begin();it!= anothermap.end();it++)
{
cout<first<<"=>"<second<<'\n';
}
return 0;
}
上述代码运行结果为
[cpp] view plaincopy
#include "stdafx.h"
#include
#include
using namespace std;
int main ()
{
map<char,int> mymap;
map<char,int>::iterator it;
mymap['a'] = 10;
mymap['b'] = 20;
mymap['c'] = 30;
mymap['d'] = 40;
mymap['e'] = 50;
mymap.insert(pair<char,int>('f',60));
cout<<"initial mymap contains :\n";
for (it = mymap.begin();it!= mymap.end();it++)
{
cout<first<<"=>"<second<<'\n';
}
it = mymap.find('b');
mymap.erase(it);
mymap.erase('c');
it = mymap.find('e');
mymap.erase(it,mymap.end());
cout<<"now mymap contains :\n";
for (it = mymap.begin();it!= mymap.end();it++)
{
cout<first<<"=>"<second<<'\n';
}
return 0;
}
上述代码运行结果为:
如果想往map/multimap中修改一个映射的值,应先插入一个新映射,再把与修改的映射删除。
4.遍历函数
iterator begin():返回首元素的迭代器指针
iterator end():返回尾元素的迭代器指针
reverse_iterator rbegin():返回尾元素的逆向迭代器指针
reverse_iterator rend():返回首元素前一个位置的迭代器指针
5.操作函数
const_iterator lower_bound(const Key& key):返回键值大于等于key的迭代器指针
const_iterator upper_bound(const Key& key):返回键值大于key的迭代器指针
int count(const Key& key) const:返回键值等于key的元素的个数
pair equal_range(const Key& key) const:返回容器中键值等于key的迭代指针[first, last)
const_iterator find(const Key& key) const:查找功能,返回键值等于key的迭代器指针
void swap(set& s):交换但映射元素
void swap(multiset& s):交换多映射元素
6.特殊函数
reference operator[](const Key& k):仅在但映射map类中,可以以数组的形式给映射添加键-值对,并可返回值的引用。