string类

1 STL 简介2 STL怎么学习3 STL缺陷4 string4.1 初识 string4.2 初步使用构造函数成员函数

5 小试牛刀Thanks♪(・ω・)ノ谢谢阅读!!!下一篇文章见!!!

1 STL 简介

现在我正式开始学习STL,这让我期待好久了,一想到不用手撕链表,手搓堆栈,心里非常爽。接下来我们先来介绍一下STL:

STL,英文全称 standard template library,中文可译为标准模板库或者泛型库,其包含有大量的模板类和模板函数,是 C++ 提供的一个基础模板的集合,用于完成诸如输入/输出、数学计算等功能。 STL 最初由惠普实验室开发,于 1998 年被定为国际标准,正式成为 C++ 程序库的重要组成部分。

主要分为这几个版本:HP STL、SGI STL、STLport、PJ STL、Rouge Wave STL 等 其中我们需要重点学习的是SGI版本: SGI版本由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。学习STL 要阅读部分源代码,主要参考的就是这个版本

2 STL怎么学习

网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构以及算法都不需要自己重新造轮子,站在前人的肩膀上,健步如飞的快速开发。那么我们应该如何学习呢? 首先就是关注官方网站 C++中查阅资料。我推荐使用这个:C++库 然后 学好英语很重要,要学会阅读文档,无论学习什么新技术,英语绝对是必不可少的。(程序员的尽头是英语)

3 STL缺陷

STL库的更新太慢了。这个得严重吐槽, 上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的

4 string

接下来让我们开始学习string类吧:

4.1 初识 string

根据上面我们进行的搜索我们可以了解到 :

string是一个代表字符串的对象。标准string类提供了类似标准字符容器的接口,而且添加了单字节操作的特性。string类 是 basic_string类模版的一个实例,使用char类型来实例化basic_string 模版类。注意这个类独立于所使用的编码来处理字节: 如果使用 multi-byte 或 多长度字符(例如UTF-8编码),这个类的所有成员(比如 长度和大小),以及该类的迭代器将仍然在该字节(而不是实际的编码字符)来操作。

可以总结为以下内容:

string是表示字符串的字符串类该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。string在底层实际是:basic_string模板类的别名,typedef basic_stringstring;不能操作多字节或者变长字符的序列

在使用string类时,必须包含#include头文件string 以及using namespace std;

4.2 初步使用

构造函数

构造函数功能string() (重点)构造空的string类对象,即空字符串string(const char* s) (重点)用C-string来构造string类对象string(size_t n, char c)string类对象中包含n个字符cstring(const string&s) (重点)拷贝构造函数

来看使用效果:

#include

#include

using namespace std;

int main() {

string s1;

string s2("Hello!");

string s3(5,'n');

string s4(s2);

cout << s1 << endl;

cout << s2 << endl;

cout << s3 << endl;

cout << s4 << endl;

return 0;

}

流操作符也在string类中进行了重载,输出很丝滑~

成员函数

成员函数作用begin()返回字符首位置 (迭代器常用 )end()返回字符结尾 (迭代器常用)size(重点)返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小empty (重点)检测字符串释放为空串,是返回true,否则返回falseclear (重点)清空有效字符reserve (重点)为字符串预留空间resize (重点)将有效字符的个数该成n个,多出的空间用字符c填充

来使用一下:

#include

#include

using namespace std;

int main() {

string s1("Hello!");

cout << s1 << endl;

//有效字符长度

cout <<"有效字符长度:" << s1.size() << endl;

//字符串所占空间

cout << "字符串所占空间:" << s1.capacity() << endl;

//实际长度(不包括‘\0')

cout << "实际长度:" << s1.length() << endl;

//检查是否为空 (为空返回1 不为空返回0)

cout <<"是否为空:" << s1.empty() << endl;

//-----------清空试试-------

cout << "\n---------清空--------\n";

s1.clear();

cout << s1 << endl;

//有效字符长度

cout << "有效字符长度:" << s1.size() << endl;

//字符串所占空间

cout << "字符串所占空间:" << s1.capacity() << endl;

//实际长度(不包括‘\0')

cout << "实际长度:" << s1.length() << endl;

//检查是否为空 (为空返回1 不为空返回0)

cout << "是否为空:" << s1.empty() << endl;

//--------更改大小-------

cout << "\n---------更改有效字符个数--------\n";

s1.resize(10, 'a');

cout << s1 << endl;

//有效字符长度

cout << "有效字符长度:" << s1.size() << endl;

//字符串所占空间

cout << "字符串所占空间:" << s1.capacity() << endl;

//实际长度(不包括‘\0')

cout << "实际长度:" << s1.length() << endl;

//检查是否为空 (为空返回1 不为空返回0)

cout << "是否为空:" << s1.empty() << endl;

return 0;

}

看看运行效果: 这样,对string就有了一个大概了解。 有些注意事项:

size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。clear()只是将string中有效字符清空,不改变底层空间大小。resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小

5 小试牛刀

家人们! 上链接!!!:字符串相加 我们来尝试使用我们刚刚学习的string来解决问题: 首先:我们不能简单的进行字符串转换为整数,然后相加,最后转换为字符串。你问我为什么? 请看VCR: 测试用例没问题,但是Leetcode给我们的数据太大了,longlong都没办法容纳。 所以我们使用最朴素的算法:竖式算法 很简单 依次相加 按运算法则进位 得到该位的数值然后插入到string即可。

class Solution {

public:

string addStrings(string num1, string num2) {

// 从个位开始,所以取字符串末位

int i = num1.length() - 1;

int j = num2.length() - 1;

// 计算所需变量

int n1 = 0,n2 = 0 ,carry = 0;

//答案string对象

string ans = "";

//开始计算

while(i >= 0 || j >= 0 || carry != 0 ){

//这里一定要写判断,不然会发生数组越界。

n1 = i >= 0 ? num1[i] - '0' : 0;

n2 = j >= 0 ? num2[j] - '0' : 0;

//得到结构就尾插

ans.push_back((n1 + n2 + carry) % 10 + '0');

//迭代

carry = (n1 + n2 + carry) / 10;

i--;

j--;

}

//注意因为我们是尾插的,所以要调换头尾顺序才可以

//这里使用 对称对调法。

for(int k = 0 ;k

char tmp = ans[k] ;

ans[k] = ans[ans.size() - 1 - k];

ans[ans.size() - 1 - k] = tmp;

}

//这个函数更方便,但是不方便解释了在这里

//reverse(ans.begin(),ans.end());

return ans;

}

};

来看效果奥:

牛批!!!!! 过啦!!!!

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。