目录
1. 什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架。
2. STL的六大组件
STL由空间配置器+容器+配接器+迭代器+算法+仿函数六大组件构成。容器:就是数据结构,换了个名字。map+set的底层就是树。
3. 标准库容器中的string类
3.1 string是一个模板,是一个字符数组,为了兼容C语言,很多接口它需要在后面手动增加一个\0
string是一个模板,他的原型是basic_string<char>。为了解决编码的问题,需要将字符串写成一个模板。常见的编码有ASCII码,起初是漂亮国人为了解决英语/阿拉伯数字在计算中的显示问题而发明的,将二进制与文字符号之间建立映射关系,ASCII码256种状态就行了。为了全世界的语言也都显示出来,使用的是万国码(Unicode),他们给出了UTF-8(兼容ASCII)、UTF-16、UTF32等解决方案。中国的是GBK(汉字内码扩展规范):国标扩展使用双字节编码方案,一个汉字用两个字节表示。256*256=65536个汉字
#include<iostream>
int main()
{
char arr[] = "比特";
cout << sizeof(arr) << endl;
arr[3]--;
arr[3]--;
arr[3]++;
arr[3]++;
arr[3]++;
arr[3]++;
return 0;
}
上述发现:数组arr在自增自减过程中发现,汉字是依据同音字相似进行编码的。在净化网络文明中就要对某个确定的字及他的同音字进行屏蔽。
回到前面的问题:为何要将basic_string写成string模板?就得到了解决,由于同一个字符的编码方式不同(同一个1按照UTF-8、UTF-16进行编码),所以需要统一一个模板。如果编码方式采用的是UTF-8用string(单字节存储)、UTF-16用u16string(两字节存储)、UTF-32用u32string(四字节存储)、宽字符(两字节存储)。这里学习的重点目标是UTF-8的string。
3.2 string类的成员函数
3.3 string类的构造函数((constructor))
3.3.1 C++98string类的构造函数提供了7种情况可供我们选择,以应对不同的情形。如下:
3.3.2 无参数的 empty string constructor (default constructor)
3.3.3 复制构造的 copy constructor
3.3.4 子字符串构造函数 substring constructor
复制 str 中从字符位置 pos 开始并跨越 len 字符的部分(如果 str 太短或 str 等于 len ,len是字符串str::npos(),则直到 str 的末尾)。
3.4 string类中的迭代器成员函数(迭代器看作指针来用)
正向迭代器,反向迭代器(r),const正向迭代器(c),const反向迭代器(c++11)。
3.5 string类中关于容量的成员函数
3.5.1 size()
3.5.2 length()
3.5.3 max_size()
返回字符串可以达到的最大长度。这个最大长度是一个固定的值为四亿两千万字节,由于已知的系统或库实现限制,这是字符串可以达到的最大潜在长度,但是不能保证对象能够达到这个长度: 在达到这个长度之前,它仍然可能无法分配存储。
3.5.4
意为:将字符串的大小调整为 n 个字符的长度。假如有一串字符大小为49字节。若n小于49,则将[n+1,49]这个区间所有的内容全部省略掉,只保留[0,n]的内容;若n大于49小于capacity,则根据函数原型需要在[50,n]之间补齐需要添加的一个字符,注意这里只能是一个字符,不能是字符串。若n大于capacity,则扩容并插入数据
3.5.5
意为:为存储字符串所分配空间的大小。这个容量不一定等于字符串长度。它可以等于或大于这个值,但是额外的空间允许对象在向 basic _ string 添加新字符时优化其操作。请注意当这个容量耗尽并且需要更多时,对象会自动扩展它(重新分配它的存储空间)。关于 base _ string 长度的理论限制是由成员 max _ size 给出的。在修改对象的任何时候,base _ string 的容量都可以改变,即使这种修改意味着大小的减少或者容量没有用尽(这与向量容器中对容量的保证形成了对比)。可以通过调用成员预留显式更改 basic _ string 的容量。
3.5.6
修改当前字符串的容量(capacity)主要是扩容,不同机器下,扩容底层实现不一样,vs下是扩容1.5倍,g++下是扩容2倍;并且vs下容量没有算/0。
我们在提前知道要多大的空间容量的情况下,reserve可以使用
3.5.7
擦除字符串的内容,该字符串变成空字符串(长度为0个字符)。
3.5.8
返回字符串是否为空(即其长度是否为0)。此函数不以任何方式修改字符串的值。若要清除字符串的内容,请参见 string: : clear。
3.5.9
请求字符串减小容量以适应其大小。可以将capacity减小到与siz同大小。不能更改其内容。
3.6 string类中关于修改的成员函数
3.6.1 operator+=():底层是由push_back实现的
通过在字符串的当前值末尾附加其他字符来扩展字符串: (参见成员函数附加其他附加选项)
3.6.2 append()
通过在字符串的当前值末尾附加其他字符来扩展该字符串。
形参可以是:1、字符串。
2、其他或者本身字符串的子字符串(从subpos位置开始,跨越sublen长度)
3、字符串的首字母的地址。
4、在s指向的字符数组中追加前n个字符的副本。
5、追加字符c的n个连续副本。
3.6.3 push_back()
将字符 c 追加到字符串的末尾,使其长度增加1。注意字符串常量是不被允许的。
3.6.4 assign():注意看源字符串比新字符串长,会先全部清空源字符串,再赋值新的字符串,不会保留源字符串
为字符串分配一个新值,替换其当前内容。
1、拷贝一个字符串。
2、复制从字符位置 subpos 开始并跨越子单元字符的部分 str (或者直到 str 结束,如果 str 太短或者子单元为 string: : npos)。
3、复制 s 指向的以空结尾的字符序列(C字符串)。
// string::assign
#include <iostream>
#include <string>
int main ()
{
std::string str;
std::string base="The quick brown fox jumps over a lazy dog.";
// used in the same order as described above:
str.assign(base);
std::cout << str << '\n';
str.assign(base,10,9);
std::cout << str << '\n'; // "brown fox"
str.assign("pangrams are cool",7);
std::cout << str << '\n'; // "pangram"
str.assign("c-string");
std::cout << str << '\n'; // "c-string"
str.assign(10,'*');
std::cout << str << '\n'; // "**********"
str.assign<int>(10,0x2D);
std::cout << str << '\n'; // "----------"
str.assign(base.begin()+16,base.end()-12);
std::cout << str << '\n'; // "fox jumps over"
return 0;
}
3.6.5 Insert():不推荐使用,时间复杂度高
可以实现头插、中间位置插入
1. pos位置处,插入字符串。
2. pos位置处,插入子字符串,子字符串是从源字符串的subpos位置处,跨过sublen长度
3. pos位置处,插入字符串。
4. pos位置处,插入长度为n的字符串。
5. pos位置处,插入n个字符c。
3.6.6 erase() :不推荐使用,时间复杂度高
1. 在pos==0的位置处,删除跨越npos长度的数据,就是头删。另外如果len比字符串长度大或者我们不给参数(就会使用npos这个很大的缺省参数),则将字符串全部删掉。
3.6.7 replace() :注意看replace是直接原位替换,源字符串比新字符串长,会保留后面的部分。
用新的内容替换字符串中从pos开始并跨越len字符的部分(或字符串中位于[i1,i2)之间的部分)
1、从pos位置,跨越len长度,被str字符串替换。
// replacing in a string
#include <iostream>
#include <string>
int main ()
{
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";
// replace signatures used in the same order as described above:
// Using positions: 0123456789*123456789*12345
std::string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string." (1)
str.replace(19,6,str3,7,6); // "this is an example phrase." (2)
str.replace(8,10,"just a"); // "this is just a phrase." (3)
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)
// Using iterators: 0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
std::cout << str << '\n';
return 0;
}
3.6.8 swap()
3.6.9 pop_back()
3.6 string类中关于查找的成员函数
3.6.1 c_string()
返回一个C字符串,字符串放在数组里面的,C字符串的意思就是:字符串的最后放了一个'/0'
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>
int main ()
{
std::string str ("Please split this sentence into tokens");
char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());
// cstr now contains a c-string copy of str
char * p = std::strtok (cstr," ");
while (p!=0)
{
std::cout << p << '\n';
p = std::strtok(NULL," ");
}
delete[] cstr;
return 0;
}
3.6.2 data()
3.6.3 get_allocator()
3.6.4 copy()
3.6.5 find()
3.6.6 rfind()
与find相反,反着找
3.6.7 substr()
取出一部分子字符串,将其作为对象进行返回
3.6.8 find_first_of()
只要目的字符串(下面的str)中有源字符串(found)中的任意一个,都将在目的字符串中标识出来
// string::find_first_of
#include <iostream> // std::cout
#include <string> // std::string
#include <cstddef> // std::size_t
int main ()
{
std::string str ("Please, replace the vowels in this sentence by asterisks.");
std::size_t found = str.find_first_of("aeiou");
while (found!=std::string::npos)
{
str[found]='*';
found=str.find_first_of("aeiou",found+1);
}
std::cout << str << '\n';
return 0;
}
5. vector的介绍及使用
5.1 vector的构造函数