c++之STL总结
c++中的STL(Stand Template Library)提供了最基本的数据结构和算法,功能十分强大。主要分为容器(数组,队列,链表,栈,集合等等),迭代器(一种对象,用来遍历容器中的元素)和常见算法(排序,反转等)
容器
字符串
包含文件:c++头文件中:#include<string>
常用方法:
-
初始化:
string str:生成空字符串 string s(str):生成字符串为str的复制品 string s(str, strbegin,strlen):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值 string s(cstr, char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值 string s(num ,c):生成num个c字符的字符串 string s(str, stridx):将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值 直接用另一个字符串赋值 如str2.assign(str1);即用str1给str2赋值. 用另一个字符串的一个子串赋值 如str3.assign(str1, 2, 3); 用一个字符串的前一段子串赋值; 如str4.assign(“World”, 5); 用几个相同的字符,赋值. 如str5.assign(10, ‘c’);
-
大小和容量
size()和length():返回string对象的字符个数,他们执行效果相同。 max_size():返回string对象最多包含的字符数,超出会抛出length_error异常 capacity():重新分配内存之前,string对象能包含的最大字符数
-
字符串的比较
C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。 在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小, 比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面) 另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。 他返回一个整数来表示比较结果,返回值意义如下:0:相等 1:大于 -1:小于 (A的ASCII码是65,a的ASCII码是97)
-
string的插入和填充
push_back():在末尾插一个字符 insert(pos char):在pos前面差一个字符
-
string拼接字符串
append():z + 操作符:
-
string的遍历:借助迭代器 或者 下标法
正向迭代器: string::iterator iter = s1.begin(); for( ; iter < s1.end() ; iter++) { cout<<*iter; } cout<<endl; 反向迭代器 string::reverse_iterator riter = s1.rbegin(); for( ; riter < s1.rend() ; riter++) { cout<<*riter; } cout<<endl; }
-
string的删除
1. iterator erase(iterator p):删除字符串中p所指的字符 2. iterator erase(iterator first, iterator last):删除字符串中迭代器区间[first,last)上所有字符 3. string& erase(size_t pos = 0, size_t len = npos):删除字符串中从索引位置pos开始的len个字符 4. void clear():删除字符串中所有字符
-
string的字符替换
string& replace(size_t pos, size_t n, const char *s):将当前字符串从pos索引开始的n个字符,替换成字符串s string& replace(size_t pos, size_t n, size_t n1, char c):将当前字符串从pos索引开始的n个字符,替换成n1个字符c 3. string& replace(iterator i1, iterator i2, const char* s):将当前字符串[i1,i2)区间中的字符串替换为字符串s
-
大小写转换
tolower()和toupper()函数 或者 STL中的transform算法 s[i] = tolower(s[i]) transform(s.begin(),s.end(),s.begin(),::tolower);
-
查找
1. size_t find (const char* s, size_t pos = 0) const:在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引, -1表示查找不到子串 2. size_t find (char c, size_t pos = 0) const:在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引,-1表示查找不到字符 3. size_t rfind (const char* s, size_t pos = npos) const:在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引,-1表示查找不到子串 4. size_t rfind (char c, size_t pos = npos) const:在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符 5. size_t find_first_of (const char* s, size_t pos = 0) const:在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引,-1表示查找不到字符 6. size_t find_first_not_of (const char* s, size_t pos = 0) const:在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到字符 7. size_t find_last_of(const char* s, size_t pos = npos) const:在当前字符串的pos索引位置开始,查找最后一个位于子串s的字符,返回找到的位置索引,-1表示查找不到字符 8. size_t find_last_not_of (const char* s, size_t pos = npos) const:在当前字符串的pos索引位置开始,查找最后一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到子串
-
排序
sort(s.begin(),s.end())
-
string的分割/截取字符串
strtok() substr()
vector
vector 是顺序容器的一种。vector 是可变长的动态数组,支持随机访问迭代器,所有 STL 算法都能对 vector 进行操作
包含文件:#include<vector>
常用方法:
函数名 | 作用 |
---|---|
vector() | 无参构造函数,将容器初始化为空 |
vector(int n) | 将容器初始化为有 n 个元素 |
vector(int n, const T & val) | 假定元素的类型是 T,此构造函数将容器初始化为有 n 个元素,每 个元素的值都是 val |
vector(iterator first, iterator last) | first 和 last 可以是其他容器的迭代器。一般来说,本构造函数初始化的结果就是将 vector 容器的内容变成与其他容器上的区间 [first, last) —致 |
void clear() | 删除所有元素 |
bool empty() | 判断容器是否为空 |
void pop_back() | 删除容器末尾的元素 |
void push_back(const T & val) | 将 val 添加到容器末尾 |
int size() | 返回容器中元素的个数 |
T & front() | 返回容器中第一个元素的引用 |
T & back() | 返回容器中最后一个元素的引用 |
iterator insert(iterator i, const T & val) | 将 val 插入迭代器 i 指向的位置,返回 i |
iterator insert( iterator i, iterator first, iterator last) | 将其他容器上的区间 [first, last) 中的元素插入迭代器 i 指向的位置 |
iterator erase(iterator i) | 删除迭代器 i 指向的元素,返回值是被删元素后面的元素的迭代器 |
iterator erase(iterator first, iterator last) | 删除容器中的区间 [first, last) |
void swap( vector & v) | 将容器自身的内容和另一个同类型的容器 v 互换 |
注意:
-
vector可以通过访问下标的形式访问元素,比如v[0];但下标只能用于获取已存在的元素。不能通过下标来添加元素。
-
可以通过find来返回某一元素在vector中的下标,用法如下:
find(vector.begin(),vector.end(),num_to_find) 该函数在指定区寻找待查找数:num_to_find,找到的话返回指向该数的一个迭代器,否则指向vector.end(); forexample: vector<int>::iterator it=find(v.begin(),v.end(),num) int index=it-v.begin() //index的值就是下标
list
包含文件:#include<list>
list 是一个双向链表。双向链表的每个元素中都有一个指针指向后一个元素,也有一个指针指向前一个元素。
list不支持下标随机读取读取元素
常用函数:
成员函数或成员函数模板 | 作 用 |
---|---|
void push_front(const T & val) | 将 val 插入链表最前面 |
void pop_front() | 删除链表最前面的元素 |
void sort() | 将链表从小到大排序 |
void remove (const T & val) | 删除和 val 相等的元素 |
remove_if() | 删除符合某种条件的元素 |
void unique() | 删除所有和前一个元素相等的元素 |
void merge(list & x) | 将链表 x 合并进来并清空 x。要求链表自身和 x 都是有序的 |
void splice(iterator i, list & x, iterator first, iterator last) | 在位置 i 前面插入链表 x 中的区间 [first, last),并在链表 x 中删除该区间。链表自身和链表 x 可以是同一个链表,只要 i 不在 [first, last) 中即可 |
说明:
-
remove_if函数 remove_if(predicate):删除满足条件的数 实例:删除list中的偶数 bool even(const int& value) { return (value % 2) == 0; } int main() { list<int> mylist{ 1, 2, 2, 2, 5, 6, 7 }; mylist.remove_if(even); for (auto it = mylist.begin(); it != mylist.end(); ++it) cout << ' ' << *it; }
-
unique函数 list_name.unique(BinaryPredicate name) name:bool name(data_type a, data_type b); // C++ program to illustrate the unique() function #include <bits/stdc++.h> using namespace std; // Function for binary_predicate bool compare(double a, double b) { return ((int)a == (int)b); } // Driver code int main() { list<double> list = { 2.55, 3.15, 4.16, 4.16, 4.77, 12.65, 12.65, 13.59 }; cout << "List is: "; // unique operation on list with no parameters list.unique(); // starts from the first element // of the list to the last for (auto it = list.begin(); it != list.end(); ++it) cout << *it << " "; // unique operation on list with parameter list.unique(compare); cout << "\nList is: "; // starts from the first element // of the list to the last for (auto it = list.begin(); it != list.end(); ++it) cout << *it << " "; return 0; }
deque
包含文件:#include<deque>
deque 也是顺序容器的一种,同时也是一个可变长数组。所有适用于 vector 的操作都适用于 deque。
与vector的比较:在 deque 中,随机存取任何元素都能在常数时间内完成(但慢于vector)。它相比于 vector 的优点是:vector 在头部删除或添加元素的速度很慢,在尾部添加元素的性能较好,而 deque 在头尾增删元素都具有较好的性能(大多数情况下都能在常数时间内完成)。它有两种 vector 没有的成员函数:
void push_front (const T & val); //将 val 插入容器的头部
void pop_front(); //删除容器头部的元素
stack
包含文件:#include<stack>
栈是一种后进先出的元素序列,访问和删除都只能对栈顶的元素(即最后一个被加入栈的元素)进行,并且元素也只能被添加到栈顶。栈内的元素不能访问。如果一定要访问栈内的元素,只能将其上方的元素全部从栈中删除,使之变成栈顶元素才可以。
成员函数 | 功 能 |
---|---|
void pop(); | 弹出(即删除)栈顶元素 |
T & top(); | 返回栈顶元素的引用。通过此函数可以读取栈顶元素的值,也可以修改栈顶元素 |
void push (const T & x); | 将 x 压入栈顶 |
multiset&set
包含文件:#include<set>
multiset 是关联容器(关联容器内部的元素都是排好序的,有:set multiset map multimap)的一种,是排序好的集合(元素已经进行了排序),并且允许有相同的元素。set与multiset的区别就是set不允许有重复元素
不能直接修改 multiset /set容器中元素的值。因为元素被修改后,容器并不会自动重新调整顺序,于是容器的有序性就会被破坏,再在其上进行查找等操作就会得到错误的结果。因此,如果要修改 multiset/set 容器中某个元素的值,正确的做法是先删除该元素,再插入新元素。(先删除后插入)
template <class Key, class Pred = less<Key>, class B = allocator<Key> > class multiset/set{}
参数说明:
第一个类型参数说明 multiset 容器中的每个元素都是 Key 类型的。第二个类型参数 Pred 用于指明容器中元素的排序规则。第三个类型参数allocator基本不用
成员函数或成员函数模板 | 作 用 |
---|---|
iterator find (const T & val); | 在容器中查找值为 val 的元素,返回其迭代器。如果找不到,返 回 end() |
iterator insert( const T & val); | 将 val 插入容器中并返回其迭代器 |
void insert(iterator first, iterator last); | 将区间 [first, last) 中的元素插人容器 |
int count( const T & val); | 统计有多少个元素的值和 val 相等 |
iterator lower_bound( const T & val); | 查找一个最大的位置 it,使得 [begin(), it) 中所有的元素者比 val 小 |
iterator upper_bound( const T & val); | 查找一个最小的位置 it,使得 [it, end()) 中所有的元素都比 val 大 |
pair <iterator, iterator > equal_range (const T & val); | 同时求得 lower_bound 和 upper_bound |
iterator erase(iterator it); | 删除 it 指向的元素,返回其后面的元素的迭代器(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样) |
iterator erase(iterator first, iterator last); | 删除区间 [first, last),返回 last(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样) |
说明:由于不能有重复元素,所以 set 中插入单个元素的 insert 成员函数与 multiset 中的有所不同,其原型如下:
pair<iterator, bool> insert(const T & val);
如果 set 的 insert 成员函数的返回值是 pair 模板类对象 x,如果 x.second 为 true,则说明插入成功,此时 x.first 就是指向被插入元素的迭代器;如果 x.second 为 false,则说明要插入的元素已在容器中,此时 x.first 就是指向原有那个元素的迭代器。
multimap&map
multimap和map是关联容器的一种,multimap和map 的每个元素都分为关键字和值两部分,容器中的元素是按关键字排序的,并且允许有多个元素的关键字相同。
注意:不能直接修改 multimap 和map容器中的关键字。因为 multimap 和map中的元素是按照关键字排序的,当关键字被修改后,容器并不会自动重新调整顺序,于是容器的有序性就会被破坏,再在其上进行查找等操作就会得到错误的结果。
定义:
template < class Key, class T, class Pred = less<Key>, class A = allocator<T> >
class multimap/map
{
...
typedef pair <const Key, T> value_type;
...
};
成员函数或成员函数模板 | 作 用 |
---|---|
iterator find( const Key & val); | 在容器中查找关键字等于 val 的元素,返回其迭代器;如果找不到,返回 end() |
iterator insert (pair <Key, T> const &p); | 将 pair 对象 p 插入容器中并返回其迭代器 |
void insert(iterator first, iterator last); | 将区间 [first, last) 插入容器 |
int count( const Key & val); | 统计有多少个元素的关键字和 val 相等 |
iterator lower_bound( const Key & val); | 查找一个最大的位置 it,使得 [begin( ), it) 中所有的元素的关键字都比 val 小 |
iterator upper_bound(const Key & val); | 查找一个最小的位置 it,使得 [it, end()) 中所有的元素的关键字都比 val 大 |
pair < iterator, iterator > equal_range (const Key & val); | 同时求得 lower_bound 和 upper_bound |
iterator erase(iterator it); | 删除 it 指向的元素,返回其后面的元素的迭代器(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样) |
iterator erase(iterator first, iterator last); | 删除区间 [first, last),返回 last(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样) |
注意:map 和 multimap 十分类似,区别在于 map 容器中元素的关键字不能重复。multimap 有的成员函数,map 都有。此外,map 还有成员函数 operator[]:
T & operator[] (Key k);
该成员函数返回 first 值为 k 的元素的 second 部分的引用。如果容器中没有元素的 first 值等于 k,则自动添加一个 first 值为 k 的元素。如果该元素的 second 成员变量是一个对象,则用无参构造函数对其初始化。