[C++]:8.C++ STL引入+string(介绍)

news/2024/10/9 11:43:14/

C++ STL引入+string(介绍)

  • 一.STL引入:
    • 1.什么是STL
    • 2.什么是STL的版本:
      • 2-1:原始版本:
      • 2-2:P. J 版本:
      • 2-3:RW 版本:
      • 2-4:SGL版本:
    • 3.STL 的六大组件:
    • 4.STL的意义:
  • 二.string类:
    • 1.string 类:
    • 2.流插入和流提取操作符:
    • 3.赋值操作符:
    • 4.string类的常见构造:
      • string()
      • string(const char*)
      • string(size_t n,char C)
      • string(const string& s) :拷贝构造
      • string(const string& s,size_t pos,size_t len = npos):范围拷贝
      • 补充:析构函数是自动调用的。
    • 5.容量相关的代码:
      • size() :返回字符串有效字符串长度数
      • length() :返回字符串有效字符串长度数
      • max_size():返回类可以开辟的空间最大的数值:
      • capacity():返回空间总大小:
        • capacity 检测代码:
      • empty():判断字符串是否为空串,空返回true ,不为空返回false
      • clear()清空有效字符
      • reserve()为字符串预留空间
      • resize() 将有效字符改成n个并且多的使用字符C填充
    • 6.string 类对象的遍历:
      • 6-1:通过重载的[]下标访问操作符:
      • 6-2:通过iterator迭代器实现遍历:
      • 6-3:通过string 的迭代器可以类比其他的容器的迭代器:
      • 6-4:通过范围for实现遍历:
    • 7.元素访问:
      • operator[]
      • at
    • 8.修改方面的方法:
      • append
      • operator+= 好处:
    • 9.两个算法:
      • 7-1:逆置算法:reverse()
      • 7-2:交换算法:
    • 8:四个练习题:
      • 8-1:把字符串转换成整数:
      • 8-2:反转字符串:
      • 8-3:字符串中第一个唯一字符:
      • 8-4:字符串相加:

一.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:下面内容后面会补充

max_size():返回类可以开辟的空间最大的数值:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:可以开辟的最大空间的大小是根据不同位数区分但是不止于此在不同的编译器下也会不一样
注意:方法美其名日可以开辟这么大的空间但是是开辟不了这么大的空间的下面可以进行验证:

capacity():返回空间总大小:

在vs下:
在这里插入图片描述

在sgl下:

1.在g++下默认空字符串是不会去开空间就是不存在默认空间。
在这里插入图片描述
在这里插入图片描述

capacity 检测代码:

在vs下检测扩容机制:
在这里插入图片描述

在sgl下检测扩容机制:
1.默认从0开始,第一个数据进来开一个空间,然后开两个,到4个一直以二倍进行扩容:
在这里插入图片描述

empty():判断字符串是否为空串,空返回true ,不为空返回false

在这里插入图片描述
在这里插入图片描述

clear()清空有效字符

在这里插入图片描述

reserve()为字符串预留空间

在这里插入图片描述

1.主要作用:就是进行容量的预开辟,前提是知道需要多大的空间:
2.我们知道默认16(包含\0),设置当前容量为20,打印的结果是31是因为,底层需要对齐的操作。(除非设置好空间的大小值是满足对齐要求的否则实际的空间大小会比设置的大一点!)
3.我们发现reserve(在vs)不可以进行容量的减少只能进行容量的增加并且影响不到原来数据。
4.总结:只能进行扩容,不可以进行分段释放。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.主要作用:就是进行容量的预开辟,前提是知道需要多大的空间:
2.我们知道默认16(包含\0),设置当前容量为20,打印的结果是31是因为,底层需要对齐的操作。(除非设置好空间的大小值是满足对齐要求的否则实际的空间大小会比设置的大一点!)
3.我们发现reserve(sgl)可以进行容量的减少只要不去影响到原来的数据。
4.总结:只能进行扩容,不可以进行分段释放。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

resize() 将有效字符改成n个并且多的使用字符C填充

在这里插入图片描述

1.resize 有两个重载:直接改变有效字符的个数用\0填充,\0不可见。
2.直接改变有效字符的个数用C填充。

1.有效字符变大:size_1 < n < capacity_1
2,进行尾插。
在这里插入图片描述

1.n<size()
尾删,删到剩n个数据,容量空间不会改变:
在这里插入图片描述

1.n>capacity_1
2.容量空间可以进行扩容
3.有效字符可以自己设置!
在这里插入图片描述

6.string 类对象的遍历:

6-1:通过重载的[]下标访问操作符:

在这里插入图片描述

基本使用:
在这里插入图片描述

循环遍历操作:
在这里插入图片描述
在这里插入图片描述
总结:通过重载的下标范围操作符是不可以进行内存空间的跳跃访问(比如链表:树:图:哈希等)的所以存在iteratoriterator迭代器实现遍历。

6-2:通过iterator迭代器实现遍历:

1.iterator 是一个类型(类似指针类型,指针指向对象的成员。)被类限定但是不被访问限定符限定:
2.通过类名+访问限定符进行访问。
3.类提供了方法去返回头尾指针(类似地址的东西)。

在这里插入图片描述
在这里插入图片描述

1.可读可写:
在这里插入图片描述

2.只读:
在这里插入图片描述

总结:返回的访问指针begin() end() 是满足左闭右开的!

6-3:通过string 的迭代器可以类比其他的容器的迭代器:

顺序表:
在这里插入图片描述
列表:
在这里插入图片描述

6-4:通过范围for实现遍历:

在这里插入图片描述

7.元素访问:

operator[]

在这里插入图片描述

at

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:
1.operator[]的下标访问越界报错是直接报错误:
2.使用at 产生越界问题会只会去抛出异常可以进行异常捕获然后打印:

8.修改方面的方法:

append

在这里插入图片描述

1.append()重载了6个方法:
2.内容非常的冗余:完全没有必要;

operator+= 好处:

在这里插入图片描述

1.可以在当前字符串后面添加字符串:
2.可以在当前字符串后面添加一个直接写的 const char*
3.可以在当前字符串后面添加一个字符:

在这里插入图片描述

9.两个算法:

7-1:逆置算法:reverse()

在这里插入图片描述

字符串的逆置:
在这里插入图片描述

7-2:交换算法:

考虑使用迭代器和循环遍历实现一个逆置:
在这里插入图片描述

8:四个练习题:

8-1:把字符串转换成整数:

在这里插入图片描述
题目链接:

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:反转字符串:

在这里插入图片描述
题目链接

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:字符串中第一个唯一字符:

在这里插入图片描述
题目链接

1.定义一个26大小的数组去通过下标对应的方法记录每个字母出现的次数。
2.双for遍历,字符串和26这个数组。遍历字符串并且确定26数组中的值是不是1。
3.找到第一个只出现一次的数就返回:
4.时间复杂度为O(n)

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;}
};

8-4:字符串相加:

在这里插入图片描述

题目链接:

在这里插入图片描述

class Solution {
public:string addStrings(string num1, string num2){int end1 = num1.size()-1;int end2 = num2.size()-1; string s1;int indx=0;while(end1>=0 || end2>=0){int p1=0;int p2=0;//字符串转数值的操作:if(end1>=0){p1=(int)(num1[end1]-'0');}if(end2>=0){p2=(int)(num2[end2]-'0');}//记录和:int sum = p1+p2+indx;indx=sum/10;sum%=10;s1.push_back((sum+'0'));end1--;end2--;}if(indx>=1){s1.push_back((indx+'0'));}reverse(s1.begin(),s1.end());return s1;}
};

http://www.ppmy.cn/news/1226582.html

相关文章

数据分析思维与模型:相关分析法

相关分析法" 是一种用于研究两个或多个变量之间关系强度和方向的统计方法。这种方法在多个领域&#xff0c;如经济学、心理学、社会科学和自然科学中都有广泛应用。其核心是通过计算相关系数来量化变量之间的相关性。以下是相关分析法的一些基本概念和步骤&#xff1a; 选…

WPF如何实现应用程序托盘

在WPF中实现应用程序托盘图标和菜单功能通常需要使用System.Windows.Forms.NotifyIcon类&#xff0c;因为WPF本身并没有直接提供这样的控件。为了使用NotifyIcon&#xff0c;你需要添加对System.Windows.Forms的引用。以下是如何实现的步骤&#xff1a; 1. 添加对 System.Wind…

Tomcat 基线安全加固操作

目录 账号管理、认证授权 日志配置 通信协议 设备其他安全要求 账号管理、认证授权 ELK-tomcat-01-01-01 编号 ELK-Tomcat-01-01-01 名称 为不同的管理员分配不同的账号 实施目的 应按照用户分配账号&#xff0c;避免不同用户间共享账号,提高安全性。 问题影响 …

为什么选择B+树作为数据库索引结构?

背景 首先&#xff0c;来谈谈B树。为什么要使用B树&#xff1f;我们需要明白以下两个事实&#xff1a; 【事实1】 不同容量的存储器&#xff0c;访问速度差异悬殊。以磁盘和内存为例&#xff0c;访问磁盘的时间大概是ms级的&#xff0c;访问内存的时间大概是ns级的。有个形象…

gRPC 四模式之 双向流RPC模式

双向流RPC模式 在双向流 RPC 模式中&#xff0c;客户端以消息流的形式发送请求到服务器端&#xff0c;服务器端也以消息流的形式进行响应。调用必须由客户端发起&#xff0c;但在此之后&#xff0c;通信完全基于 gRPC 客户端和服务器端的应用程序逻辑。 为什么有了双向流模式…

C语言循环结构 while循环

while循环 while循环语句概述while循环输出20个数while循环注意事项 while循环语句概述 作用&#xff1a;满足循环条件&#xff0c;执行循环语句 语法&#xff1a;while(循环条件){ 循环语句 } 解释&#xff1a;只要循环条件的结果为真&#xff0c;就执行循环语句 while循环输…

【Linux】进程间通信 -- 共享内存

共享内存 共享内存是SystemV标准进程间通信的一种&#xff0c;该标准还有消息队列和信号量&#xff0c;但下文主要介绍共享内存&#xff0c;然后在谈一下信号量的内容。SystemV标准的进程间通信可以看做单机版的进程间通信。 // 1. log.hpp #pragma once#include <iostrea…

ClickHouse建表优化

1. 数据类型 1.1 时间字段的类型 建表时能用数值型或日期时间型表示的字段就不要用字符串&#xff0c;全String类型在以Hive为中心的数仓建设中常见&#xff0c;但ClickHouse环境不应受此影响。 虽然ClickHouse底层将DateTime存储为时间戳Long类型&#xff0c;但不建议存储Long…