String类(STL开始)

相信大家都知道STL在C++中的重要性,作为其模板库中的一部分,包含了常见的数据结构和算法,是C++的标准库
而我们今天要讲的String类(String底层是一个字符顺序数组的顺序表对象,可以归类为容器),其实其诞生于STL之前,并不属于STL,但是你却可以从中看到属于STL的一角,相信学了String类之后,在后面学习STL时,vector等类对大家来说一定手到擒来

为什么学习String类

C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问

在OJ中,有关字符串的题目一般也是由String类形式出现,很少有人去用C库中的字符串操作函数

标准库中的String类

String类基本了解

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
    总结:
  6. string是表示字符串的字符串类
  7. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  8. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  9. 不能操作多字节或者变长字符的序列。在使用string类时,必须包含#include头文件以及using namespace std;

String类常用接口说明

1. String类对象常用构造

在这里插入图片描述
我们分别在编译器中使用这些函数试试
在这里插入图片描述

相信通过这个演示,大家已经知道string类的构造函数是如何使用的了,不过我们一般不使用第三种,其的重要性不如其他三个

2. string类容量操作

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

接下来也是用代码来举例子
在这里插入图片描述

3. string类对象的访问及遍历操作

在这里插入图片描述
代码演示:
在这里插入图片描述

需要注意的是,operator[]是重载运算符,后面我们在自行实现string类时,可以仔细观察

4. string类对象的修改操作

在这里插入图片描述
代码例子:
在这里插入图片描述
注意:

  1. 在string尾部追加字符时,s.push_back( c ) / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。(所以实际意思就是+=好用)
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好

5.string类非成员函数

一般来说,我们知道非成员函数就是没有写在类内部的函数,所以像重载函数一些的函数都需要写在外部,不然的话会出现无法改变函数的参数顺序的情况,毕竟在我们先前写日期类时就出现过这些问题

在这里插入图片描述
关系操作(relational operators):有==(等于) !=(不等于) <(小于) <=(小于等于) >(大于) >=(大于等于)

上面的几个接口大家了解一下,下面的OJ题目中会有一些体现他们的使用。string类中还有一些其他的操作,这里不一一列举,大家在需要用到时不明白了查文档即可。

代码展示:
在这里插入图片描述

牛刀小试

在这里插入图片描述
正确答案

class Solution {
public:
    string reverseOnlyLetters(string s) {
        int left = 0;
        int right = s.size() - 1;
        while (left < right) {
            if (!isalpha(s[left])) {
                left++;
            } else if (!isalpha(s[right])) {
                right--;
            } else {
                swap(s[left], s[right]);
                left++;
                right--;
            }
        }
        return s;
    }
};

容易错误答案

class Solution {
public:
    string reverseOnlyLetters(string s) {
        int begin = 0;
        int end = s.size() - 1;
        while (begin < end) {
            if (!isalpha(s[begin]))
                begin++;
            if (!isalpha(s[end]))
                end--;

            swap(s[begin], s[end]);
            begin++;
            end--;
        }

        return s;
    }
};

这里我们拿一个错误用例:7_28,本来由于其都是非英文字母,所以其实本来应该直接循环结束也不会更改任何一个位置,但是我们只考虑了可能会有1次非英文字母,导致了在检查了一次之后就直接交换,产生错误,最后的结果直接错误,而如果用if else一句,一次循环只有一次判断,虽然会麻烦一点,但是不会出现这样的错误。也有人会说,可以用while语句,但是用while语句的话,有时会超出时间,所以我们这里也不推荐,if else语句是我们比较建议的一种写法

在这里插入图片描述
正确答案

class Solution {
public:
    int firstUniqChar(string s) {
        int *a = (int*)calloc(sizeof(int), 256);
        for (int i = 0; i < s.size(); i++) {
            a[s[i]]++;
        }

        for (int i = 0; i < s.size(); i++) {
            if (a[s[i]] == 1) {
            	free(a);
                return i;
            }
        }

		free(a);
        return -1;
    }
};

在这里插入图片描述
正确答案

#include <iostream>
using namespace std;

int main() {
    string s;
    getline(cin,s);

    if(s.empty())
        cout<<0<<endl;//如果是空串,直接输出0

    size_t rfound=s.rfind(' ');//找到最后一个空格
    if(rfound){
        cout<<s.size()-1-rfound<<endl;//如果找到了,就用中间段相减得出结果
    }

    else{
        cout<<s.size()<<endl;//没有空格,现在的就是最后一个单词,也就是现在的单词长度就是字符串最后一个单词
    }
}// 64 位输出请用 printf("%lld")

在这里插入图片描述
正确答案

class Solution {
public:
    bool isPalindrome(string s) {
        string str;
        str.reserve(s.size()+1);//提前reserve,只是为了后面不用边加边扩容
        for(int i=0;i<s.size();i++){
            if(isalpha(s[i])){
                str+=tolower(s[i]);//如果是字母,直接尾插小写的字母,不管它小写的还是大写的
            }

            if(isdigit(s[i])){
                str+=s[i];//字母就直接尾插
            }
        }
        string str_begin=str;//保存反转前的str
        reverse(str.begin(),str.end());
        string rstr=str;//保存反转后的str
        if(rstr==str_begin){
            return true;
        }

        else{
            return false;
        }
    }
};

在这里插入图片描述
正确答案

#include <algorithm>
#include <string>

class Solution {
public:
    std::string addStrings(std::string num1, std::string num2) {
        if (num1 == "0")
            return num2;
        if (num2 == "0")
            return num1;//完美解决了0的三种情况

        std::string str;//用来存储相加后的字符串
        std::string::reverse_iterator rit1 = num1.rbegin();
        std::string::reverse_iterator rit2 = num2.rbegin();//从最后一位开始相加,其实就是做竖式的过程
        int sum = 0;//当位数
        int carry = 0;//进位

        while (rit1 != num1.rend() && rit2 != num2.rend()) {
            sum = (*rit1 - '0') + (*rit2 - '0') + carry;
            carry = sum / 10;
            str += (sum % 10) + '0';
            rit1++;
            rit2++;
        }
		
		//下面是防止两个一个长一个短的情况
        while (rit1 != num1.rend()) {
            sum = (*rit1 - '0') + carry;
            carry = sum / 10;
            str += (sum % 10) + '0';
            rit1++;
        }

        while (rit2 != num2.rend()) {
            sum = (*rit2 - '0') + carry;
            carry = sum / 10;
            str += (sum % 10) + '0';
            rit2++;
        }
		
		//如果最后加的那一下又有进位,不能忘掉
        if (carry > 0) {
            str += carry + '0';
        }

        std::reverse(str.begin(), str.end());//因为我们用+=,是尾插不是头插,所以最后要反转过来
        return str;
    }
};

这道题我们要注意一个地方,那就是我们是在字符串中加减,所以我们不可以直接用字符加减,而是要用其减去’0‘得到其原来的值

上面的是博主自己做的(迭代器),可能看上去很复杂麻烦,下面是力扣的标准答案,大家看一下应该会觉得很简洁

class Solution {
public:
    string addStrings(string num1, string num2) {
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        string ans = "";
        while (i >= 0 || j >= 0 || add != 0) {
            int x = i >= 0 ? num1[i] - '0' : 0;
            int y = j >= 0 ? num2[j] - '0' : 0;
            //这里避免了两个位数不同的问题
            int result = x + y + add;
            ans.push_back('0' + result % 10);
            add = result / 10;
            i--;
            j--;
        }
        // 计算完以后的答案需要翻转过来
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/784657.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL安装时initializing database失败

问题页面&#xff1a; 解决方法&#xff1a; 1.勾选红框中的选项&#xff1a; 2.将下图红框中全部改为英文&#xff1a; 然后一路next就可以了。

洛谷 P3613 学习用map代替大大大数组的好题

题目链接&#xff1a;P3613 【深基15.例2】寄包柜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目截图&#xff1a; 题意分析&#xff1a; 非常简单的存入和取出操作 唯一的 “难点” 在于 数组开不到 a[100007][100007]&#xff0c;会暴内存 非常巧妙的引入 map 来解决…

广州银行多份招股书数据货不对板:内控风险难平,IPO曲折前行

作者|芋圆 来源|贝多财经 6月29日&#xff0c;广州银行第五次更新了招股说明书。 作为制造业大省的头部城商行&#xff0c;广州银行的发展一直备受关注。拆解可知&#xff0c;广州银行2023年在盈利能力、内控、资本充足性、资产质量等方面的表现&#xff0c;凸显了该行接下来…

Linux三剑客(grep、awk和sed)操作及与管道结合使用

1. 总览 grep、sed和awk被称为Linux三剑客&#xff0c;是因为它们在文本处理和数据操作方面极其强大且常用。 Linux三剑客在文件处理中的作用&#xff1a; grep&#xff08;数据查找定位&#xff09;&#xff1a;文本搜索工具&#xff0c;在文件中搜索符合正则表达式的文本内容…

小阿轩yx-Haproxy搭建Web群集

小阿轩yx-Haproxy搭建Web群集 Haproxy 简介 提供高可用性 能做出标准的负载均衡 支持虚拟主机 具备健康检查能力 能用于各式各样的代理 轻量级代理环境 解决方案优势 免费 快速 可靠 特性 特别适用于那些负载特大的web站点&#xff0c;这些站点通常又需要会话保持或…

明明已经安装了python中的某个库,但是还是报错ModuleNotFoundError: No module named ‘sklearn‘

问题&#xff1a; 明明已经安装了python中的某个库&#xff0c;但是还是报错ModuleNotFoundError: No module named sklearn 解决方法&#xff1a; 卸载重新安装一下即可 pip uninstall scikit-learn pip install scikit-learn 成功解决&#xff01;&#xff01;&#xff…

高创新 | CEEMDAN-VMD-GRU-Attention双重分解+门控循环单元+注意力机制多元时间序列预测

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 高创新 | CEEMDAN-VMD-GRU-Attention双重分解门控循环单元注意力机制多元时间序列预测 本文提出一种基于CEEMDAN 的二次分解方法&#xff0c;通过样本熵重构CEEMDAN 分解后的序列&#xff0c;复杂序列通过VMD…

【Threejs进阶教程-着色器篇】1. Shader入门(ShadertoyShader和ThreejsShader入门)

ThreejsShader入门 关于本Shader教程认识ShaderShader和Threejs的关系WebGLShaderThreejsShaderShadertoyShader其他Shader 再次劝退数学不好的人从ShaderToy开始Shader的代码是强类型glsl的类型&#xff0c;变量&#xff0c;内置函数&#xff0c;关键字关于uv基于UV的颜色处理…

PCL 点云FPFH特征描述子

点云FPFH特征描述子 一、概述1.1 FPFH概念1.2 基本原理1.3 PFH和FPFH的区别二、代码实现三、结果示例一、概述 1.1 FPFH概念 快速点特征直方图(FPFH)描述子:计算 PFH 特征的效率其实是十分低的,这样的算法复杂度无法实现实时或接近实时的应用。因此,这篇文章将介绍 PFH 的简…

【java web 01】3小时快速学习前端知识(收藏备用)

3小时快速学习前端知识【全栈专用】 一、教程简介1.1 Java 开发为何学Web技术1.2 课程设计1.3 课前准备 二、HTML2.1 Html简介2.1.1 HTML、CSS、JS分别有什么作用2.1.2 什么是HTML2.1.3 什么是标记语言 2.2 Hello&#xff0c;Html2.2.1 HTML基础结构2.2.2 专业词汇2.2.3 语法细…

面试经典150题

合并两个有序数组 两个按非递减顺序排列的整数数组nums1和nums&#xff0c;另有两个整数m和n&#xff0c;分别表示nums1和nums2中的元素数组。 请合并nums2到nums1中&#xff0c;使合并后的数组同样按非递减顺序排列。 直接合并后排序 class Solution { public:void merge(…

解码Python字符串:‘r‘、‘b‘、‘u‘和‘f‘前缀的全面指南

&#x1f4d6; 正文 1 字符串前加’r’ 表示原始字符串&#xff0c;消除转义 print(abc\nde) # abc # deprint(rabc\nde) # abc\nde在下面这个列子中&#xff0c;如果不在路径字符串前面加r那么&#xff0c;路径中的空格就会出现问题 print(rD:\01 programming\09python\py…

【ARM系列】GIC600AE功能安全

GIC600AE功能安全 1.GIC600AE主要安全机制分布图&#xff1a;2.Fault Management Unit1.GIC block的错误如何上报到FMU&#xff1f;2.汇总到FMU的错误如何上报&#xff1f;3.Error Record format4.Safety Mechanism GIC600AE在原GIC600版本基础上增加了FuSa功能&#xff0c;所增…

RIP环境下的MGRE网络

首先将LSP的IP地址进行配置 其他端口也进行同样的配置 将serial3/0/1配置25.0.0.2 24 将serial4/0/0配置35.0.0.2 24 将GE0/0/0配置45.0.0.2 24 进行第二步 R1与R5之间使用ppp的pap认证 在R5中进行配置 在aaa空间中创建账号和密码 将这个账号和密码使用在ppp协议中 然后…

zdppy+onlyoffice+vue3解决文档加载和文档强制保存时弹出警告的问题

解决过程 第一次排查 最开始排查的是官方文档说的 https://api.onlyoffice.com/editors/troubleshooting#key 解决方案。参考的是官方的 https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Python.Example.zip 基于Django的Python代码。 …

使用 Hugging Face 模型时遇到的问题

题意&#xff1a; I load a float32 Hugging Face model, cast it to float16, and save it. How can I load it as float16? 我加载了一个float32的Hugging Face模型&#xff0c;将其转换为float16&#xff0c;并保存了。我该如何以float16的形式加载它呢&#xff1f; 问题…

2.硬盘和内存区别

2.2 磁盘比内存慢几万倍&#xff1f; 存储器方面的设备&#xff0c;分类比较多&#xff0c;那我们肯定不能只买一种存储器&#xff0c;比如你除了要买内存&#xff0c;还要买硬盘&#xff0c;而针对硬盘我们还可以选择是固态硬盘还是机械硬盘。 相信大家都知道内存和硬盘都属…

【大模型LLM面试合集】大语言模型架构_attention

1.attention 1.Attention 1.1 讲讲对Attention的理解&#xff1f; Attention机制是一种在处理时序相关问题的时候常用的技术&#xff0c;主要用于处理序列数据。 核心思想是在处理序列数据时&#xff0c;网络应该更关注输入中的重要部分&#xff0c;而忽略不重要的部分&…

java webservice 根据wsdl文件生成客户端代码;webservice可视化测试工具SOAPUI;

背景 最近要对接HIS系统&#xff0c;对方提供的接口是webservice的&#xff08;有点古老&#xff09;&#xff0c;对方是webservice的提供方&#xff0c;提供了wsdl文件&#xff0c;我方需要根据wsdl文件生成java代码&#xff0c;intellij idea生成webservice客户端代码支持的…