- STL 初识
- vector 存放内置数据类型
- vector 存放自定义数据类型
- vector 容器嵌套容器
- string 容器
- string 基本概念
- string 构造函数
- string 赋值操作
- string 字符串拼接
- string 查找和替换
- string 比较
- string 字符存取
- string 插入和删除
- string 子串
STL 基本概念
- STL 标准模板库
- STL 从广义上分为:容器、算法和迭代器
- 容器和算法之间通过迭代器进行无缝连接
- STL 几乎所有的代码都采用了模板类或者模板函数
STL 六大组件
》》STL 大体上分为六大组件,分别是容器、算法、迭代器、仿函数、适配器和空间配置器
- 容器:各种数据结构,如 vector、list、deque、set、map 等,用来存放数据
- 算法:各种常用的算法,如 sort、find、copy、for_each 等
- 迭代器:扮演了容器和算法之间的胶合剂
- 仿函数:行为类似函数,可作为算法的某种策略
- 适配器:一种用来修饰容器、仿函数或者迭代器接口的东西
- 空间配置器:负责空间的配置与管理
STL 中容器、算法和迭代器
》》容器
- STL 容器就是运用一些最广泛的数据类型实现出现
- 常用的数据结构:数组、链表、树、栈、队列、集合、映射表等
- 可以分为序列式容器和关联式容器二类
- 序列式容器强调值的排序,其中的元素都有固定的位置
- 关联式容器属于二叉树结构,其中的元素没有固定的位置关系
》》算法
- 有限的步骤解决逻辑或数学上的问题,称为算法
- 算法分为质变算法和非质变算法二类
- 质变算法指运算过程会改变区间元素内容,如拷贝、替换和删除等
- 非质变算法指运算过程不会改变区间元素内容,如查找、计数、遍历和寻找极值等
》》迭代器
- 提供一种方法,使之能够依序访问容器中的每个元素,而又无需暴露容器内部的表示方式
- 每个容器都有属于自己的迭代器,迭代器的使用非常类似于指针
- 迭代器可以分为输入、输出、前向、双向、随机迭代器
容器:vector(所需头文件 #include
算法:for_each(所需头文件 #include )
迭代器:vector
#includeusing namespace std; #include // 容器 #include // 算法 void Print(int value) { cout << value << " "; } int main() { // 1. 创建一个 vector 容器,数组 vector v; // 2. 向容器中插入数据 v.push_back(10); v.push_back(20); v.push_back(30); // 3. 通过迭代器访问容器中的数据 vector ::iterator itBegin = v.begin(); // 起始迭代器,指向容器中的第一个元素 vector ::iterator itEnd = v.end(); // 结束迭代器,指向容器中最后一个元素的下一个位置 // itBegin 和 itEnd 都属于指针 // 3.1 第一种遍历方法 while (itBegin != itEnd) { cout << *itBegin << " "; // 10 20 30 itBegin++; } cout << endl; // 3.2 第二种遍历方法 for (vector ::iterator it = v.begin(); it < v.end(); it++) { cout << *it << " "; // 10 20 30 } cout << endl; // 3.3 第三种遍历方法 -- 利用 STL 提供遍历的算法 for_each(v.begin(), v.end(), Print); // 10 20 30 cout << endl; system("pause"); return 0; }
解释:如下程序创建了一个容器数组 v;并利用 push_back 函数插入了三条 int 类型的数据;随后通过迭代器访问数组中的元素:访问方法如下举了三个例子,第一种和第二种类似,用二个变量接收容器 v 的起始地址和末尾后(末尾后一个)地址,用遍历的方式访问元素,第三种则是通过算法 for_each,其中传入了三个参数,第一个和第二个参数分别是起始地址和末尾后地址,第三个参数传递了一个函数名,函数形参为数组中的元素
vector 存放自定义数据类型自定义 Person 数据类型,其中包含二个成员属性(Name_ 和 Age_)
第一种:vector 容器数组中存放 Person 对象
#includeusing namespace std; #include #include // 容器 // 自定义数据类型 class Person { public: Person(string name, int age) { Name_ = name; Age_ = age; } public: string Name_; int Age_; }; int main() { // 1. 创建容器对象 vector v; // 2. 创建数据并插入数据 Person p1("A", 1); Person p2("B", 2); Person p3("C", 3); v.push_back(p1); v.push_back(p2); v.push_back(p3); // 3. 输出数组中的数据 for (vector ::iterator it = v.begin(); it < v.end(); it++) { cout << "Name:" << (*it).Name_ << " Age:" << (*it).Age_ << endl; } // outputs:Name:A Age:1 // Name:B Age:2 // Name:C Age:3 system("pause"); return 0; }
第二种:vector 容器数组中存放 Person 对象地址
#includevector 容器嵌套容器using namespace std; #include #include // 容器 // 自定义数据类型 class Person { public: Person(string name, int age) { Name_ = name; Age_ = age; } public: string Name_; int Age_; }; int main() { // 1. 创建容器对象 vector v; // 2. 创建数据并插入数据地址 Person p1("A", 1); Person p2("B", 2); Person p3("C", 3); v.push_back(&p1); v.push_back(&p2); v.push_back(&p3); // 3. 输出数组中的数据 -- 此时 *it 变为一个指针 for (vector ::iterator it = v.begin(); it < v.end(); it++) { cout << "Name:" << (*it)->Name_ << " Age:" << (*it)->Age_ << endl; } // outputs:Name:A Age:1 // Name:B Age:2 // Name:C Age:3 system("pause"); return 0; }
#includestring 容器 string 基本概念using namespace std; #include #include // 容器 // 自定义数据类型 class Person { public: Person(string name, int age) { Name_ = name; Age_ = age; } public: string Name_; int Age_; }; int main() { // 1. 创建容器对象 vector > v; // 2. 创建数据对象并为之插入数据 -- 次容器 vector v1; vector v2; vector v3; for (int i = 0; i < 3; i++) { v1.push_back(i + 1); v2.push_back(i + 2); v3.push_back(i + 3); } // 3. 往主容器中插入数据 v.push_back(v1); v.push_back(v2); v.push_back(v3); // 4. 遍历主容器对象 for (vector >::iterator it = v.begin(); it < v.end(); it++) { for (vector ::iterator iit = (*it).begin(); iit < (*it).end(); iit++) { cout << (*iit) << " "; } cout << endl; } // outputs:1 2 3 // 2 3 4 // 3 4 5 system("pause"); return 0; }
本质
string 是 C++ 风格的字符串,而 string 本质上是一个类
string 和 char * 的区别
- char * 是一个指针
- string 是一个类,类内部封装了 char *,是一个 char * 型的容器
特点
- string 类内部封装了很多成员方法,如查找、拷贝、删除、替换和插入等
- string 管理 char * 所分配的内存,不用担心复制越界和取值越界问题
构造函数原型
- string(); // 创建一个空的字符串,如 string str;
- string(const char * s); // 使用字符串 s 初始化
- string(const string& s); // 使用一个 string 对象初始化另一个 string 对象
- string(int n, char c); // 使用 n 个字符 c 初始化
#includestring 赋值操作using namespace std; #include int main() { // 1. 默认构造 string s1; cout << s1 << endl; // 空字符串 // 2. 有参构造 const char * str = "love"; // C 风格字符串 string s2(str); cout << s2 << endl; // love // 3. 使用一个 string 对象初始化字符串 string s3(s2); cout << s3 << endl; // love // 4. 使用 n(10) 个字符 c(g) 初始化 string s4(10, 'g'); cout << s4 << endl; // gggggggggg system("pause"); return 0; }
赋值的函数原型
- string& operator=(const char* s); // 字符串 s 赋值给当前的字符串
- string& operator=(const string &s); // 字符串对象 s 赋值给当前的字符串
- string& operator=(char c); // 字符赋值给当前的字符串
- string& assign(const char *s); // 字符串 s 赋值给当前的字符串
- string& assign(const char *s, int n); // 字符串 s 的前 n 个字符赋值给当前的字符串
- string& assign(const string &s); // 字符串对象 s 赋值给当前字符串
- string& assign(int n, char c); // 将 n 个字符 c 赋值给当前字符串
#includestring 字符串拼接using namespace std; #include int main() { // 默认构造 string s1; // 空字符串 // 有参构造 string s2("you"); // 使用 5 个 r 初始化字符串 string s3(5, 'r'); // 等号赋值操作 // 1. 字符串 "love" 赋值给字符串 s1 s1 = "love"; cout << s1 << endl; // love // 2. 字符串对象 s2 赋值给 s1 s1 = s2; cout << s1 << endl; // you // 3. 字符对象 c 赋值给字符串 s1 s1 = 'm'; cout << s1 << endl; // m // assign 函数赋值操作 // 1. 字符串 "his" 赋值给字符串 s1 s1.assign("his"); cout << s1 << endl; // his // 2. 字符串 "his" 前 n 个元素赋值给字符串 s1 s1.assign("her", 2); cout << s1 << endl; // he // 3. 字符串 s3 赋值给字符串 s1 s1.assign(s3); cout << s1 << endl; // rrrrr // 4. 将 n(5) 个字符 c(b) 赋值给字符串 s1 s1.assign(5, 'b'); cout << s1 << endl; // bbbbb system("pause"); return 0; }
字符串拼接的函数原型(append 函数不可拼接字符)
- string& operator+=(const char * s); // 拼接字符串 s
- string& operator+=(const char c); // 拼接字符 c
- string& operator+=(const string & s); // 拼接字符对象 s
- string& append(const char *s); // 拼接字符串 s
- string& append(const char *s, int n); // 拼接字符串 s 的前 n 个字符
- string& append(const string &s); // 拼接字符串对象 s
- string& append(const string &s, int pos, int n); // 拼接从索引 pos 开始的 n 个字符
#includestring 查找和替换using namespace std; #include int main() { // 构造函数 string s1; // 空字符串 // 有参构造 string s2("you"); // 加等号拼接字符串 // 1. 拼接字符串 s s1 += "i"; cout << s1 << endl; // i // 2. 拼接字符 c s1 += 'l'; cout << s1 << endl; // il // 3. 拼接字符串对象 s2 s1 += s2; cout << s1 << endl; // ilyou // append 函数拼接字符串 // 1. 拼接字符串 s s1.append("beat"); cout << s1 << endl; // ilyoubeat // 2. 拼接字符串 s 的前 n 个字符 s1.append("ful", 2); cout << s1 << endl; // ilyoubeatfu // 3. 拼接字符串对象 s2 s1.append(s2); cout << s1 << endl; // ilyoubeatfuyou // 4. 拼接字符串从索引位置 2 开始的 2 个字符 s1.append("abcdefg", 2, 2); cout << s1 << endl; // ilyoubeatfuyoucd system("pause"); return 0; }
字符串查找:查找指定字符串是否存在
- int find(const string& s, int pos = 0) const; // 从索引为 pos 往后查找字符串对象 s 第一次出现的位置
- int find(const char* s, int pos = 0) const; // 从索引为 pos 往后查找字符串 s 第一次出现的位置
- int find(const char* s, int pos, int n) const; // 从索引为 pos 往后查找字符串前 n 个字符第一次出现的位置
- int find(const char c, int pos = 0) const; // 从索引为 pos 往后查找字符 c 第一次出现的位置
- int rfind(const string& s, int pos = npos) const; // (逆序)从索引为 pos 往前查找字符串对象 s 第一次出现的位置
- int rfind(const char* s, int pos = npos) const; // (逆序)从索引为 pos 往前查找字符串 s 第一次出现的位置
- int rfind(const char* s, int pos, int n) const; // (逆序)从索引为 pos 往前查找字符串前 n 个字符第一次出现的位置
- int rfind(const char c, int pos = npos) const; // (逆序)从索引为 pos 往前查找字符 c 第一次出现的位置
#includeusing namespace std; #include int main() { // 有参构造 string s1("iloveyoubabyyoukonw!"); // 有参构造 string s2("ou"); // 初始化字符 string s3; s3 = 'u'; // 正序查找 // 1. 从索引为 0 往后查找字符串对象 s2,返回第一次出现位置的索引 cout << s1.find(s2) << endl; // 6 // 2. 从索引为 0 往后查找字符串 "ou",返回第一次出现位置的索引 cout << s1.find("ou") << endl; // 6 // 3. 从索引为 0 往后查找字符串 "ou" 的前 1 个元素,返回第一次出现位置的索引 cout << s1.find("ou", 0, 1) << endl; // 2 // 4. 从索引为 0 往后查找字符 'v',返回第一次出现位置的索引 cout << s1.find('v') << endl; // 3 // 逆序查找 // 1. (逆序)从索引为 20 往前查找字符串对象 s2,返回第一次出现位置的索引 cout << s1.rfind(s2) << endl; // 13 // 2. (逆序)从索引为 20 往前查找字符串 "ou",返回第一次出现位置的索引 cout << s1.rfind("ou") << endl; // 13 // 3. (逆序)从索引为 20 往前查找字符串 "ou" 的前 1 个元素,返回第一次出现位置的索引 cout << s1.rfind("ou", 20, 1) << endl; // 16 // 4. (逆序)从索引为 20 往前查找字符 'v',返回第一次出现位置的索引 cout << s1.rfind('v') << endl; // 3 system("pause"); return 0; }
字符串替换:在指定的位置替换字符串
- string& replace(int pos, int n, const string &s); // 从 pos 开始的 n 个字符替换为字符串对象 s
- string& replace(int pos, int n, const char* s); // 从 pos 开始的 n 个字符替换为字符串 s
#includestring 比较using namespace std; #include int main() { // 有参构造 string s1("loveyou"); // 有参构造 string s2("me"); // 1. 替换字符串对象 s2 s1.replace(4, 3, s2); cout << s1 << endl; // loveme // 2. 替换字符串 s1.replace(4, 2, "him"); cout << s1 << endl; // lovehim system("pause"); return 0; }
函数原型
- int compare(const string &s) const; // 与字符串对象 s 比较
- int compare(const char *s) const; // 与字符串 s 比较
比较方式:根据字符的 ASCII 码;相等则返回 0;大于则返回 1;小于则返回 -1;
#includestring 字符存取using namespace std; #include int main() { // 有参构造 string s1("loveyou"); // 有参构造 string s2("me"); // 1. 与字符串对象比较 cout << s1.compare(s2) << endl; // -1 cout << s1.compare(s1) << endl; // 0 // 2. 与字符串对比 cout << s1.compare("loveyou") << endl; // 0 cout << s1.compare("loveyoue") << endl; // -1 cout << s1.compare("loveyo") << endl; // 1 system("pause"); return 0; }
string 中单个字符存取方式有二种
- char& operator[](int n); // 通过索引取字符
- char& at(int n); // 通过 at 方式取字符
#includestring 插入和删除using namespace std; #include int main() { // 有参构造 string s1("loveyou"); // 第一种方式 for (int i = 0; i < s1.size(); i++) { cout << s1[i] << " "; // l o v e y o u } cout << endl; // 第二种方式 for (int j = 0; j < s1.size(); j++) { cout << s1.at(j) << " "; // l o v e y o u } cout << endl; system("pause"); return 0; }
函数原型
- string& insert(int pos, const char* s); // 插入字符串 s
- string& insert(int pos, const string& s); // 插入字符串对象 s
- string& insert(int pos, int n, char c); // 在指定位置插入 n 个字符 c
- string& erase(int pos, int n); // 删除从 pos 开始的 n 个字符
#includestring 子串using namespace std; #include int main() { // 有参构造 string s1("loveyou"); string s2("his"); // 1. 插入字符串 s1.insert(0, "me"); cout << s1 << endl; // meloveyou // 2. 插入字符串对象 s1.insert(2, s2); cout << s1 << endl; // mehisloveyou // 3. 在指定位置插入 n 个字符 s1.insert(0, 3, 'a'); cout << s1 << endl; // aaamehisloveyou // 4. 删除从 pos 开始的 n 个字符 s1.erase(0, 5); cout << s1 << endl; // hisloveyou system("pause"); return 0; }
函数原型
string substr(int pos, int n) const; // 返回由 pos 开始的 n 个字符组成的字符串
#includeusing namespace std; #include int main() { // 有参构造 string s1("loveyou"); // 构造函数 string s2; s2 = s1.substr(0, 3); cout << s2 << endl; // lov s2 = s1.substr(2, 4); cout << s2 << endl; // veyo system("pause"); return 0; }



