C++ STL引入+string(介绍)
- 一.STL引入:
-
- 1.什么是STL
- 2.什么是STL的版本:
-
- 2-1:原始版本:
- [2-2:P. J 版本:](#2-2:P. J 版本:)
- [2-3:RW 版本:](#2-3:RW 版本:)
- 2-4:SGL版本:
- [3.STL 的六大组件:](#3.STL 的六大组件:)
- 4.STL的意义:
- 二.string类:
-
- [1.string 类:](#1.string 类:)
- 2.流插入和流提取操作符:
- 3.赋值操作符:
- 4.string类的常见构造:
-
- string()
- [string(const char*)](#string(const char*))
- [string(size_t n,char C)](#string(size_t n,char C))
- [string(const string& s) :拷贝构造](#string(const string& s) :拷贝构造)
- [string(const string& s,size_t pos,size_t len = npos):范围拷贝](#string(const string& s,size_t pos,size_t len = npos):范围拷贝)
- 补充:析构函数是自动调用的。
- 5.容量相关的代码:
-
- [size() :返回字符串有效字符串长度数](#size() :返回字符串有效字符串长度数)
- [length() :返回字符串有效字符串长度数](#length() :返回字符串有效字符串长度数)
- capacity():返回空间总大小:
- [empty():判断字符串是否为空串,空返回true ,不为空返回false](#empty():判断字符串是否为空串,空返回true ,不为空返回false)
- clear()清空有效字符
- reserve()为字符串预留空间
- [resize() 将有效字符改成n个并且多的使用字符C填充](#resize() 将有效字符改成n个并且多的使用字符C填充)
- [6.string 类对象的遍历:](#6.string 类对象的遍历:)
-
- 6-1:通过重载的[]下标访问操作符:
- 6-2:通过iterator迭代器实现遍历:
- [6-3:通过string 的迭代器可以类比其他的容器的迭代器:](#6-3:通过string 的迭代器可以类比其他的容器的迭代器:)
- 6-4:通过范围for实现遍历:
- 7.两个算法:
- 8:三个练习题:
一.STL引入:
1.什么是STL
STL(standard template libaray 标准模板库):是C++ 标准库(还包括有IO库:智能指针库:)的重要组成部分,不仅仅是一个可以复用的组件库,而且还是一个包含数据结构与算法的软件框架。
2.什么是STL的版本:
2-1:原始版本:
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。
唯一的条件就是也需要向原始版本一样做开源使用。(如果你写了一个库是基于STL的内容进行的修改那么这个库需要进行开源)......
HP 版本--所有STL实现
2-2:P. J 版本:
由P.J plauger 开发,继承自hp版本,windows visual C++ 采用,不可以公开和修改。
2-3:RW 版本:
由Rouge Wage 开发,继承自hp版本,被C++ buider 采用,不可以公开或者修改。
2-4:SGL版本:
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码,主要参考的就是这个版本。
3.STL 的六大组件:
4.STL的意义:
STL是C++中重要的作品有了STL许多底层的数据结构和算法都不需要自己重新造轮子。可以让我们站在巨人的肩膀上进行快速高效的开发!
总结:STL学习的三个境界:能用,明理,能扩展。
二.string类:
引入:在C语言中,字符串是用\0结尾的一串字符的集合,为了方便操作C语言提供了一系列的字符串系列的函数,但是这些库函数是和字符串是分离开来的不符合面向对象的思想,并且字符串空间的数据需要用户自己管理和释放容易导致产生越界访问!
1.string 类:
1.我们会发现string类是由一个basic_string 一个类模板实例化生成的一个类的typedef 重命名的。
2.使用需要带头文件()和 using namespace std;
2.流插入和流提取操作符:
string类重载了流插入和流提取操作符,他们是类的友元函数。
运行代码可以得到几个结论:
1.cout正常打印字符串内容包括空格:
2.cin不可以插入中间存在空格的字符串,只能把第一个空格之前的内容输入进字符串对象中。
3.赋值操作符:
支持:
string=string
string = const char*
string = char
4.string类的常见构造:
string()
构造空的字符串类对象
string(const char*)
用常量字符串构造string对象:
string(size_t n,char C)
个数+字符的形式的构造函数:
string(const string& s) :拷贝构造
string(const string& s,size_t pos,size_t len = npos):范围拷贝
1.从s的pos位置开始拷贝len个字符到新的字符串里面去!
2.npos的默认缺省值为-1 但是因为len类型为size_t 类型所以默认值是非常大的!
3.len的值比较大的时候如果被拷贝的字符串后面没有字符了就不会拷贝了!
补充:析构函数是自动调用的。
5.容量相关的代码:
size() :返回字符串有效字符串长度数
length() :返回字符串有效字符串长度数
总结:为什么有两个方法都可以计算字符串的有效字符个数,因为STL库的出现没有string这个类早,早的时候使用的是length计算个数。后来STL库出来之后使用size方法计算各种类的元素个数所以又给string类添加了一个方法用来计算有效字符个数。
ps:下面内容后面会补充
capacity():返回空间总大小:
empty():判断字符串是否为空串,空返回true ,不为空返回false
clear()清空有效字符
reserve()为字符串预留空间
resize() 将有效字符改成n个并且多的使用字符C填充
6.string 类对象的遍历:
6-1:通过重载的[]下标访问操作符:
基本使用:
循环遍历操作:
总结:通过重载的下标范围操作符是不可以进行内存空间的跳跃访问(比如链表:树:图:哈希等)的所以存在iteratoriterator迭代器实现遍历。
6-2:通过iterator迭代器实现遍历:
1.iterator 是一个类型(类似指针类型,指针指向对象的成员。)被类限定但是不被访问限定符限定:
2.通过类名+访问限定符进行访问。
3.类提供了方法去返回头尾指针(类似地址的东西)。
1.可读可写:
2.只读:
总结:返回的访问指针begin() end() 是满足左闭右开的!
6-3:通过string 的迭代器可以类比其他的容器的迭代器:
顺序表:
列表:
6-4:通过范围for实现遍历:
7.两个算法:
7-1:逆置算法:reverse()
字符串的逆置:
7-2:交换算法:
考虑使用迭代器和循环遍历实现一个逆置:
8:三个练习题:
8-1:把字符串转换成整数:
c
class Solution {
public:
int StrToInt(string str)
{
string::iterator it = str.end();
int count = 1;
int sum = 0;
while (it != str.begin())
{
it--;
char tmp = (*it);
if (tmp >= 48 && tmp <= 57)
{
sum += (((int)(tmp - '0')) * count);
}
else
{
if (it == str.begin())
{
if (tmp == '-')
{
sum *= -1;
}
else
{
break;
}
}
else
{
sum = 0;
break;
}
}
count *= 10;
}
return sum;
}
};
8-2:反转字符串:
c
class Solution {
public:
void reverseString(vector<char>& s) {
reverse(s.begin(),s.end());
vector<char>::iterator it = s.begin();
while(it!=s.end())
{
cout<<*it;
it++;
}
}
};
8-3:字符串中第一个唯一字符:
c
class Solution {
public:
int firstUniqChar(string s) {
int arr[26] = { 0 };
string::iterator it = s.begin();
while (it != s.end())
{
int indx = (int)(*it - 97);
arr[indx]++;
it++;
}
string::iterator it1 = s.begin();
int count = 0;
while (it1 != s.end())
{
for (int i = 0; i < 26; i++)
{
if (arr[(int)((*it1) - 97)] == 1)
{
return count;
}
}
count++;
it1++;
}
return -1;
}
};