目录
STL
什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
通俗上来讲,STL就是将常见的数据结构以模板的方式进行封装,包含常见的泛型算法。
常见的数据结构:顺序表、链表、队列、栈、堆、二叉树、哈希表
STL的六大组件
a.容器
容器是存储其他对象(其元素)集合的容器对象。它们是作为类模板实现的,这使得作为元素支持的类型具有很大的灵活性。
容器管理其元素的存储空间,并提供成员函数来直接或通过迭代器(与指针具有相似属性的引用对象)访问它们。
容器复制编程中非常常用的结构:动态数组(vector)、队列(queue),堆栈(stack)、堆(priority_queue),链表(目录),树木set(),关联数组(地图)...
通俗上来说容器就是对常见的数据进行封装
b算法
c.迭
d.适配器
e.仿函数
f.空间配置器
STL自己封装的内存池。
string类
为什么要有string类?
string类的介绍
通过查阅相关网站我们了解到:
typedef basic_string<char> string;
String类string是表示字符序列的对象。标准string类提供了对这类对象的支持,其接口类似于标准字节容器的接口,但增加了专门设计用于操作单字节字符串的功能。
string类是basic_string类模板的一个实例,该模板使用char(即字节)作为其字符类型,并具有默认的char_traits和分配器类型。
string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits
和allocator作为basic_string的默认参数
这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个
类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
总结
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
4. 不能操作多字节或者变长字符的序列。
使用string类时必须包含头文件(#include<string>),以及using namespace std;
string类常用接口说明
1.string类常见构造函数
string()
功能:构造空字符串
string(const char*)
功能:从功能实现上可以理解为可以给string初始化
事实上是调用字符串来构造string类对象
string(size_t n,char c)
功能:用n个字符c来构造string;
string(const string& str)
功能:用string str来拷贝构造
2.string类常见容量操作
size_t size() const
功能:返回字符串的有效长度
size_t length() const
功能:返回字符串的有效长度
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下都是使用size
size_t capacity() const
功能:返回空间总大小(不包括'\0')。
bool empty()
功能:判断字符串是否为空
void clear()
功能:清除有效字符
int main(){
string s("hello");
int size = s.size();
int length = s.length();
int capacity = s.capacity();
cout << capacity << endl;
if (s.empty())
cout<<" capacity:" << "该字符串为空!" << endl;
else
cout << "该字符串的长度为" << length << endl;
s.clear();
if (s.empty())
cout << "该字符串为空!" << endl;
else
cout << "该字符串的长度为" << length << endl;
cout <<" capacity:" <<capacity<< endl;
system("pause");
return 0;
}
void reserve(size_t newcapacity)
功能:为字符串预留空间即扩容,只改变容量,不改变有效元素的个数(根据传入的实参)
为了更深的了解reserve的扩容规则,作者在vs2013环境下测试了reserve的扩容规则:
扩容的步骤:开辟新空间,拷贝元素,释放旧空间,返回新空间
为什么当newcapacity<=15时capacity突然发生变化了呢?
在string底层结构中,c++开发者为其设计了一个长度为16(包括‘\0’)字符数组
voidresize(size_t newsize ,char c='\0')
功能:有效字符改为n个,多出的空间用字符(实参字符)来填满,如果不传参数,那么用'\0'填充。
void TestResize()
{
string s("hello");
s.resize(12);//增大有效元素个数但没有扩容
cout << "size:" << s.size() << "capacity:" << s.capacity() << endl;
s.resize(18);//增大有效元素个数且进行扩容
cout << "size:" << s.size() << "capacity:" << s.capacity()<< endl;
s.resize(10);//减小有效元素观察是否减少容量
cout << "size:" << s.size() << "capacity:" << s.capacity()<< endl;
s.resize(2);
cout << "size:" << s.size() << "capacity:" << s.capacity()<< endl;
}
如果newsize>capacity,则需要扩容,如果resize<size,则s中有效元素个数减少至newsize个。
3.string类的访问元素以及遍历操作
string有四种遍历方式
1.字符串元素下标
void Test1()
//字符串下标访问遍历
{string s("hello world");
for (int i=0; i < (int)s.size(); i++){
cout << s[i] ;
}
}
这里的s是一个对象,s[i]之所以编译器能识别是因为string库中有operato []操作符重载函数。对[]进行了重载
2.范围for
void Test2()
//范围for
{
string s("hello boy");
for (auto temp : s)
{
cout << temp;
}
}
3.迭代器正向
void Test3()
//正向迭代器
{
string s(5, 'b');
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
++it;
}
}
4迭代器反向
void Test4()
//迭代器反向
{
string s("hello");
string:: reverse_iterator it = s.rbegin();
while (it != s.rend())
{
cout << *it << endl;
++it;
}
}
string类的元素访问
1.operator[]
直接string类对象.[元素下标]的形式就可以
2.front---c++11提出
char&front()
获取string类对象元素列表的第一个元素
3.char&back()
获取string类对象元素列表的最后一个有效元素
4.string类的元素修改操作
1.void push_back(char c)
功能:在字符串末尾尾插
void Test1(string &str){
str.push_back('!');
}
2.string& append(const string&str)
功能:在字符串后追加一个字符串
void Test2(string &str){
string a("world");
str.append(a);
}
3.oeprator+=
string&operator+=(const string& str)
末尾追加一个string对象
string& operator+=(const char*s)
末尾追加C中字符
string& operator+=(const char c);
末尾追加字符
功能:字符串后追加一个字符串str/字符/C中的字符串
void Test3(string &str){
string a("boy");
str += a;
char c = 'b';
str += c;
str += 'c';
}
const char* c_str()const
功能:返回c格式字符串
void Test4(string &str){
cout <<str.c_str();
}
find
1.string::npos是string类中一个静态成员常量
npos表示size_t的最大值
由于npos是这一个无符号数,string类中定义为-1,转化为十进制有符号数刚好为最大值,常用来搭配find使用,如果找到返回元素下标pos如果没找到返回-1(打印的时候结果肯定不是-1,是一个很大的值,这是由于npos是无符号的)
find的几种使用场景
string (1) | size_t find (const string& str, size_t pos = 0) const; |
---|---|
c-string (2) | size_t find (const char* s, size_t pos = 0) const; |
buffer (3) | size_t find (const char* s, size_t pos, size_t n) const; |
character (4) | size_t find (char c, size_t pos = 0) const |
(1)针对要查找一个string对象是否在另一个string对象中出现,如果出现,返回第一次出现的位置,如果没找到则返回npos;
(2)我们要查找
//string::find
void Test1(string &str){
string tar("yo");
int position;
position = str.find(tar);
if (position != string::npos)
cout << "find it" << position << "位置" << endl;
}
void Test2(string &str){
int position;
position = str.find("you");
if (position != string::npos)
cout << "find it" << position << "位置" << endl;
}
void Test3(string &str){
int position;
position = str.find("you",0,3);
if (position != string::npos)
cout << "find it" << position << "位置" << endl;
}
void Test4(string &str){
int position;
position = str.find('r', 0);
if (position != string::npos)
cout << "find it" << position << "位置" << endl;
}
int main(){
string s("are you ok?");
Test1(s);
Test2(s);
Test3(s);
Test4(s);
system("pause");
return 0;
}
size_t rfind
功能:使用方法和find相同,但不同的是find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置,rfind向前查找
string substr (size_t pos=0,size_t len =npos)const
功能:从字符串pos的位置开始,截取n个字符,然后将其返回。
1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般
情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好
5.string类非成员函数
operator +
void swap(string&x,string&y);
功能:交换两个string类中的字符串。
operator<<
功能:输出运算符重载
operator>>
功能:输入运算符重载
operator>>(string)要空格就自动结束了
getline
(1) | istream& getline (istream& is, string& str, char delim); istream& getline (istream&& is, string& str, char delim); |
---|---|
(2) | istream& getline (istream& is, string& str); istream& getline (istream&& is, string& str) |
功能:获取一行字符串
relational operators
(1) | bool operator== (const string& lhs, const string& rhs); bool operator== (const char* lhs, const string& rhs); bool operator== (const string& lhs, const char* rhs); |
---|---|
(2) | bool operator!= (const string& lhs, const string& rhs); bool operator!= (const char* lhs, const string& rhs); bool operator!= (const string& lhs, const char* rhs); |
(3) | bool operator< (const string& lhs, const string& rhs); bool operator< (const char* lhs, const string& rhs); bool operator< (const string& lhs, const char* rhs); |
(4) | bool operator<= (const string& lhs, const string& rhs); bool operator<= (const char* lhs, const string& rhs); bool operator<= (const string& lhs, const char* rhs); |
(5) | bool operator> (const string& lhs, const string& rhs); bool operator> (const char* lhs, const string& rhs); bool operator> (const string& lhs, const char* rhs); |
(6) | bool operator>= (const string& lhs, const string& rhs); bool operator>= (const char* lhs, const string& rhs); bool operator>= (const string& lhs, const char* rhs); |
功能:大小比较
参考资料:www.cplusplus.com