1. 基本概念
- STL:(Standard Template Library)标准模板库。
(1) 从广义上分为:容器(container)、算法(algorithm)、迭代器(iterator),容器和算法通过迭代器无法连接。
(2)STL 几乎所有的代码都采用了模板类或者模板函数,这相比传统的由函数和类组成的库来说提供了更好的代码重用机会。 - 容器:即各种数据结构,入数组、链表、栈、树、图等,用来存放各种数据。
(1)序列式容器:元素的存放顺序与存入是的顺序相同,数组、链表、栈皆为序列式容器;
(2)关联式容器:各元素之间没有严格的物理顺序,即容器中未保存元素存入时的逻辑顺序, 如Set/multiset容器 Map/multimap容器;在值中选择一个值作为关键字Key
,起到索引作用。 - 算法:各种常用的算法,如排序、查找、拷贝、遍历等。
(1)质变算法:运算过程中更改区间内元素的内容,如拷贝、替换、删除等;
(2)废止便算法:不会更改元素内容,如查找、计数、遍历等。 - 迭代器:容器与算法之间的胶合剂。
(1)迭代器的设计思维-STL的关键所在,STL的中心思想在于将容器(container)和算法(algorithms)分开,彼此独立设计,最后再一贴胶着剂将他们撮合在一起。
(2)迭代器相当于指针,其重载了指针操作符。
2. 遍历容器中的数据
2.1 普通数据类型
void test01()
{
//定义一个int类型的容器
vector<int>v;
//插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
//利用迭代器遍历容器中的数据
//v.begin()指向容器中第一个元素的地址
vector<int>::iterator itBegin = v.begin();
//v.end()指向容器最后一个元素下一个的地址
vector<int>::iterator itEnd = v.end();
while (itBegin != itEnd)
{
cout << *itBegin << endl;
itBegin++;
}
}
2.2 自定义类
void test02()
{
//1.创建容器
vector<Person> v;
//2.插入
//2.1创建对象
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
//2.2尾插
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
//3.1创建迭代器遍历
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "name:" << (*it).name << " age:" << (*it).age << endl;
}
/*******自定义类指针**********/
//1.创建容器
vector<Person*> pv;
//2.插入
//2.2尾插
pv.push_back(&p1);
pv.push_back(&p2);
pv.push_back(&p3);
pv.push_back(&p4);
//3.1创建迭代器遍历
for (vector<Person*>::iterator it = pv.begin(); it != pv.end(); it++)
{
cout << "name:" << (*it)->name << " age:" << (*it)->age << endl;
}
}
2.3 嵌套容器
void test03()
{
//1.创建容器
//1.1创建父容器
vector<vector<int>> v;
//1.2创建子容器
vector<int> v1;
vector<int> v2;
vector<int> v3;
//2.插入容器
//2.1插入子容器
for (int i = 0; i < 4; i++)
{
v1.push_back(i + 1);
v2.push_back(i + 10);
v3.push_back(i + 100);
}
//2.2插入父容器
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
//3.遍历容器
//3.1建立父迭代器
for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
{
//3.2建立子迭代器
for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
{
cout << (*vit) << " ";
}
cout << endl;
}
}
3. 字符串string容器
3.1 基本赋值操作
- 构造函数初始化
string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
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赋给当前字符串
string& assign(const string &s, int start, int n);//将s从start开始n个字符赋值给字符串
void test01()
{
//1.参数为字符串string& operator=(const char* s)
string s1 = "abcde";
//2.拷贝构造函数string& operator=(const string& s)
string s2(s1);
//3.连续n个字符
string s3(5, 'a');
//4.把字符串s的前n个字符赋给当前的字符串string& assign(const char* s, int n);
string s4;
s4.assign("abcdefg", 3);
//5.将s从start开始n个字符赋值给字符串string& assign(const string& s, int start, int n)
string s5;
s5.assign(s2, 1, 3);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
cout << s5 << endl;
}
3.2 string存取字符操作
- 通过
[]
方式取字符
char& operator[](int n);
通过[]
方式取字符时,若取的为止越界,则程序直接崩溃;
- 通过
at
方法获取字符
char& at(int n);
通过at
方法获取字符时,若出现越界,则回扔出异常。
void test02()
{
string str = "abcde";
for (int i = 0; i < str.size(); i++)
{
cout << str[i] << endl;
cout << str.at(i) << endl;
}
try
{
//cout << str[100] << endl;
cout << str.at(100) << endl;
}
catch (exception & a)
{
cout << a.what() << endl;
}
}
4. 拼接、查找和替换
4.1 拼接
- 通过重载操作符
+=
来实现。
string& operator+=(const string& str);//重载+=操作符
string& operator+=(const char* str);//重载+=操作符
string& operator+=(const char c);//重载+=操作符
- 通过
append
函数来实现。
string& append(const char *s);//把字符串s连接到当前字符串结尾
string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
string& append(const string &s);//同operator+=()
string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
string& append(int n, char c);//在当前字符串结尾添加n个字符c
void test03()
{
string s1 = "我";
string s2 = "爱中华";
string s3 = "民族";
s1 += s2;
s1.append(s3);
cout << s1 << endl;
}
4.2 查找
- 通过
find()
函数来实现: 从首字符开始查找。
int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
- 通过rfind()函数来实现: 从尾字符向首字符查找。
int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从pos开始查找
int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从pos开始查找
int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后一次位置
int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
void test04()
{
string s1 = "abcdefghdef";
string s2 = "def";
cout << s1.find(s2) << endl;
cout << s1.find(s2, 4) << endl;
cout << s1.rfind(s2) << endl;
}
4.3 替换
通过repalce函数实现。
string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为字符串s
void test04()
{
string s2 = "def";
s2.replace(1, 2, "aaaaaa");
cout << s2 << endl;
}
5. 字符串的比较和字串
5.1 比较
compare
函数是逐个比较字符串中字符的ascll
码。- 若字符相同,则字符串长的大。
- 大于返回1, 等于返回0, 小于返回-1;
int compare(const string &s) const;//与字符串s比较
int compare(const char *s) const;//与字符串s比较
void test05()
{
string s1 = "abc";
string s2 = "bbc";
string s3 = "abcd";
cout << s1.compare(s2) << endl;
cout << s1.compare(s3) << endl;
cout << s2.compare(s3) << endl;
}
5.2 字串
- 基本语法
string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成的字符串
void test06()
{
string s1 = "abcdefg";
string s2 = s1.substr(0, 5);
cout << s2 << endl;
}
- 提高:将
www.abcde.com.cn
的每个节点分开插入到容器中并遍历容器
/*提高*/
void test07()
{
string s1 = "www.abcde.com.cn";
//0.创建容器
vector<string> v;
//1.从0位置开始查找.
int start = 0;
int pos = -1;
//2.循环提取
while (true)
{
//3.查找.的位置
pos = s1.find(".", start);
//3.1若未找到.的位置,直接停止循环
if (pos == -1)
{
string s2 = s1.substr(start, s1.size() - start);
v.push_back(s2);
break;
}
//4.截取出从头开始到.为止的字符串
string s2 = s1.substr(start, pos - start);
//5.插入容器
v.push_back(s2);
//6.查找的位置从上一次找的.后面开始
start = pos + 1;
}
//7.遍历容器
for (vector<string>::iterator it = v.begin(); it < v.end(); it++)
{
cout << (*it) << endl;
}
}
6. 插入、删除、转换
- 插入:通过
insert()
函数实现
string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c);//在指定位置插入n个字符c
- 删除:通过
erase()
函数实现
string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
- string与const char*转换
(1)在c++中存在一个从const char*
到string
的隐式类型转换,却不存在从一个string
对象到C_string
的自动类型转换。对于string
类型的字符串,可以通过c_str()
函数返回string
对象对应的C_string
.
(2)通常整个程序中应坚持使用string
类对象,直到必须将内容转化为char*
时才将其转换为C_string
.
const char* c_str(string& str) const:
- 大小写转换:通过
toupper
和tolower
来实现
char toupper(int c);
char tolower(int c);
void test08()
{
string s1 = "aBCde";
//1.插入
string s2 = s1.insert(1, "666");
cout << s2 << endl;
//2.删除
string s3 = s2.erase(1, 3);
cout << s3 << endl;
//3.string与const char*转换
const char* s4 = "aaaaa";
//3.1 const char*->string
string s5 = string(s4);
cout << s5 << endl;
//3.2 string->const char*
const char* s6 = s5.c_str();
cout << s6 << endl;
//4.大小写转换
string s7 = "aBcDeF";
for (int i = 0; i < s7.size(); i++)
{
s7[i] = toupper(s7[i]);
cout << s7[i];
s7[i] = tolower(s7[i]);
cout << s7[i];
}
}