数据结构04附录01:字符串大写转小写[C++]

news2024/11/15 22:48:36

 

图源:文心一言

上机题目练习整理~🥝🥝

本篇作为字符串的代码补充,提供了3种(差别并不大)解法以及函数的详细解释,供小伙伴们参考~🥝🥝

前文:🌸数据结构04:串的存储结构与KMP算法_串的三种存储方式-CSDN博客

  • 第1版:在力扣新手村刷题的记录,方法一与方法二是 文心一言 老师提供的建议,方法三是力扣的官方解法~🧩🧩

编辑:梅头脑🌸

题目:709. 转换成小写字母 - 力扣(LeetCode)


📇目录

🧵转换小写字母的题目

🧩题目

🌰方法一:for循环 + 转小写函数tolower

🌰方法二:transform转换 + 转小写函数tolower

🌰方法三:for循环 + ASCII码

🔚结语


🧵转换小写字母的题目

🧩题目

给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。

示例 1:

输入:s = "Hello"
输出:"hello"

示例 2:

输入:s = "here"
输出:"here"

示例 3:

输入:s = "LOVELY"
输出:"lovely"

🌰方法一:for循环 + 转小写函数tolower

📇算法思路

  • 算法思想:使用for循环,对于字符串中的每个字母转小写~
  • 时间复杂度:O(n),其中n是数组的长度,该代码对字符串中的每个字符都进行了操作。
  • 空间复杂度:O(1),其中n是数组的长度,该代码直接在原字符串上进行操作,没有使用额外的存储空间。

 ⌨️算法代码

class Solution {
public:
    string toLowerCase(string s) {    // 返回类型为string的方法,名为toLowerCase。它接受一个名为s的字符串参数
        for (char &c : s) {           // 基于范围的for循环,用于遍历字符串s中的每一个字符。这里使用的是C++11中的范围for循环语法
           c = std::tolower(c);       // 对于字符串s中的每个字符c,都调用了std::tolower函数。这个函数是C++标准库中的一个函数,用于将大写字母转换为小写字母
        }
        return s;  // 返回转换后的字符串  // 返回原始字符串s
    }
};

 ⌨️温馨提示

可能问题:请注意,以下写法可能会导致下图的执行错误:

  • 第4行直接写为:“for (char c : s)”,而非for (char &c : s)
  • 第5行直接写为:“std::tolower(c);”,而非c = std::tolower(c);

问题所在:由于std::tolower(c);没有将结果存储回原字符c,所以实际上有些字符未被转换为小写。因此,当您尝试返回原始字符串时,它仍然是原来的大小写形式。

        

由于std::tolower(c);没有将结果存储回原字符c,所以实际上有些字符未被转换为小写。因此,当您尝试返回原始字符串时,它仍然是原来的大小写形式。

⌨️函数解释

基于范围的for循环(Range-based for loop) 

是C++11中引入的一种新特性,它允许我们更简洁、更直观地遍历容器(如数组、字符串、向量等)中的元素。

这种循环的基本语法如下:

for (element_type value : container) {  
    // 循环体  
}
  • element_type 是容器中元素的类型,
  • value 是我们为每个元素定义的临时变量名,
  • container 是要遍历的容器。

 为什么使用基于范围的for循环?

  1. 简洁性:它避免了使用传统的迭代器,使代码更简洁。
  2. 直观性:对于不熟悉迭代器的开发者来说,基于范围的for循环更直观,更容易理解。
  3. 性能:在某些情况下,基于范围的for循环可能比使用迭代器更快,因为编译器可以进行更多的优化。

例子

假设我们有一个整数数组,并想打印出数组中的所有元素:

使用传统的迭代器:

#include <iostream>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    for (int *it = arr; it != arr + 5; ++it) {
        std::cout << *it << ' ';
    }

    return 0;
}

 使用基于范围的for循环:

#include <iostream>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    for (int value : arr) {
        std::cout << value << ' ';
    }

    return 0;
}

 基于范围的for循环不仅适用于数组,还适用于所有支持迭代器的容器,如std::vectorstd::stringstd::list等。

例如本题就是基于std::string的遍历~~

🌰方法二:transform转换 + 转小写函数tolower

📇算法思路

  • 算法思想:将循环替换为transform,也可以达到对字符串中的字符逐个操作的结果;
  • 时间复杂度:O(n),其中n是数组的长度,该代码对字符串中的每个字符都进行了操作。
  • 空间复杂度:O(1),其中n是数组的长度,该代码直接在原字符串上进行操作,没有使用额外的存储空间。

 ⌨️算法代码

class Solution {
public:
    string toLowerCase(string s) { 
        std::transform(s.begin(), s.end(), s.begin(), ::tolower);  // 将所有字符转换为小写  
        return s;  // 返回转换后的字符串  
    }
};
⌨️函数解释
  1. std::transform: 这是C++标准库中的函数,用于对容器中的元素进行转换。
  2. s.begin(), s.end(): 这两个参数定义了一个范围,即从字符串s的开始到结束。这意味着我们要对字符串s中的所有字符进行操作。
  3. s.begin(): 这是输出迭代器,表示转换后的字符应该被写入的位置。因为我们要将转换后的字符覆盖原字符串,所以输出迭代器就是s.begin()
  4. ::tolower: 这是一个函数指针,指向C标准库中的tolower函数。这个函数的作用是将大写字母转换为小写字母。

⌨️知识扩展

transform

参考原文:C++ transform(STL transform)函数用法详解 (biancheng.net)

transform() 可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。

  • 这个序列可以是字符串,如本题;
  • 这个序列可以是向量容器,例如以下举栗在向量中存储的数据 从 摄氏度转换到 华氏度。
    • std::vector<double> deg_C {21.0, 30.5, 0.0, 3.2, 100.0};
      std::vector<double> deg_F(deg_C.size());
      std::transform(std::begin(deg_C), std::end(deg_C), std::begin(deg_F),[](double temp){ return 32.0 + 9.0*temp/5.0; });
      //Result 69.8 86.9 32 37.76 212
    • 第1行代码创建了一个名为 deg_C 的向量,并初始化了五个浮点数;
    • 第2行代码创建了一个新的向量 deg_F,其大小与 deg_C 相同。这个新向量被初始化为空。
    • 第3行使用了 std::transform 算法来转换 deg_C 中的数据,并将结果存储在 deg_F 中。
      • std::begin(deg_C) 和 std::end(deg_C):这两个函数是定义输入序列的输入迭代器,指向 deg_C 向量的开始和结束。
      • std::begin(deg_F):是目的位置的第一个元素的输出迭代器,指向 deg_F 向量的开始。(值得注意的是,如果是rbegin,则为反向迭代器,指向容器中的最后一个元素)
      • [](double temp){ return 32.0 + 9.0*temp/5.0; }:这是一个 lambda 函数,用于将摄氏度转换为华氏度。转换公式是:F = C × 9/5 + 32。

上述代码感兴趣可以直接运行这个:

#include <iostream>
#include <vector>
#include <algorithm>  // 为了使用 std::transform

int main() {
    std::vector<double> deg_C {21.0, 30.5, 0.0, 3.2, 100.0};
    std::vector<double> deg_F(deg_C.size());

    std::transform(std::begin(deg_C), std::end(deg_C), std::begin(deg_F), [](double temp) { return 32.0 + 9.0 * temp / 5.0; });

    // 打印转换结果
    for (const auto& temp : deg_F) {
        std::cout << temp << " ";
    }

    return 0;
}

用静态数组也可以,不过文心老师温馨提醒,实际使用过程中,数组长度一般是固定的,灵活性小于容器,且不负责内存管理~

#include <iostream>

int main() {
    double deg_C[] = {21.0, 30.5, 0.0, 3.2, 100.0};
    double deg_F[5];  // 注意大小固定为5

    for (size_t i = 0; i < 5; ++i) {
        deg_F[i] = 32.0 + 9.0 * deg_C[i] / 5.0;
    }

    // 打印转换结果
    for (size_t i = 0; i < 5; ++i) {
        std::cout << deg_F[i] << " ";
    }

    return 0;
}

🌰方法三:for循环 + ASCII码

📇算法思路

  • 算法思想:
    • ASCII码中,小写字母a-z的码值为97-122。因此,要将大写字母A-Z转换为小写字母,只需将对应的大写字母码值加上32即可;
    • 例如,大写字母A的码值为65,转换为小写字母a的码值为97(65+32);

图源:java数据类型转换_java里面long转换对应的ascii码-CSDN博客

⌨️算法代码

class Solution {
public:
    string toLowerCase(string s) {
        for (char& ch: s) {
            if (ch >= 65 && ch <= 90) {    // 如果字符为大写,即ASCII码介于65-90
                ch |= 32;                  // 对 ch 的 ASCII码与 32 做按位或运算,替代与 32的加法运算。
            }
        }
        return s;
    }
};

作者:力扣官方题解
来源:https://leetcode.cn/problems/to-lower-case/solutions/1151839/zhuan-huan-cheng-xiao-xie-zi-mu-by-leetc-5e29/

⌨️算法解释

第6行完全可以使用 ch = ch + 32;而官方采用了按位或运算ch |= 32,这么修改的条件如下:

  • 正好[65,90] 对应的二进制表示为 [(01000001)2,(01011010)2],观察从高到低第3位恒为0;
  • 32对应的二进制为(00100000)2,观察从高到低第3位恒为1;
  • 0和1相与刚好就是相加的意思,对于这道题,可以用或代替相加的功能;
  • 不晓得是不是业内主流做法,因为按位与比相加快很多;相反,如果不能保证被加数与加数的相应位数刚好错开,就不能这么玩了。

🔚结语

博文到此结束,写得模糊或者有误之处,欢迎小伙伴留言讨论与批评,督促博主优化内容{例如有错误、难理解、不简洁、缺功能}等,博主会顶锅前来修改~~😶‍🌫️😶‍🌫️

我是梅头脑,本片博文若有帮助,欢迎小伙伴动动可爱的小手默默给个赞支持一下,感谢点赞小伙伴对于博主的支持~~🌟🌟

同系列的博主博文在以下链接~~🌸🌸

数据结构_梅头脑_的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_42789937/category_12262100.html?spm=1001.2014.3001.5482

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM的汽车客运订票系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

漏油控制器有用吗?漏油监测器多少钱一个?

漏油控制器也可以被称作漏油监测器、漏油传感器&#xff0c;是漏油检测系统里的一部分&#xff0c;一般是和漏油检测绳组合在一起使用&#xff0c;用来检测油罐、输油管道、油类化工厂等场合是否有油料泄露。很多人刚开始可能会觉得难以置信&#xff0c;这么一个小东西就可以检…

Sqoop入门指南:安装和配置

Sqoop是一个强大的工具&#xff0c;用于在Hadoop和关系型数据库之间高效传输数据。在本篇文章中&#xff0c;将深入探讨如何安装和配置Sqoop&#xff0c;以及提供详细的示例代码。 安装Java和Hadoop 在开始安装Sqoop之前&#xff0c;首先确保已经成功安装了Java和Hadoop。Sqo…

魔众文库新版本:自动化功能让文库管理更轻松!

VIP界面升级&#xff0c;文档文本自动解析、虚拟数量升级&#xff0c;小程序自适应 [新功能] Values 组件新增 countFixed 属性&#xff0c;固定显示数量 [新功能] 后台文库管理分页调整为 10&#xff0c;100&#xff0c;,100 [新功能] 后台文库管理增加虚拟数量批量修改功能…

Golang基础入门及Gin入门教程(2024完整版)

Golang是Google公司2009年11月正式对外公开的一门编程语言&#xff0c;它不仅拥有静态编译语言的安全和高性能&#xff0c;而 且又达到了动态语言开发速度和易维护性。有人形容Go语言&#xff1a;Go C Python , 说明Go语言既有C语言程序的运行速度&#xff0c;又能达到Python…

抖店开通后下一步做什么?最新教程如下,手把手教你设置店铺功能

我是王路飞。 上篇文章给你们说了下2024年最新的抖店开通、入驻流程&#xff0c;还没看到的可以去看下。 既然店铺已经开通了&#xff0c;那接下来自然就是运营店铺了。 很多新手小白也是开店很积极&#xff0c;但真正开始运营的时候就抓瞎了&#xff0c;不知道店铺开通后下…

【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(下)

盲点问题解析之HashMap工作原理全揭秘 承接上文创建HashMap对象参考容量&#xff08;capacity&#xff09;Hashmap内部有一个机制扩容阈值&#xff08;threshold&#xff09;负载因子&#xff08;loadFactor&#xff09; HashMap存储元素的过程HashMap的put方法JDK8的扩容机制N…

使用curl命令在Linux上进行HTTP请求

在Linux系统中&#xff0c;curl是一个非常强大的命令行工具&#xff0c;用于发送各种类型的HTTP请求。通过简单的命令&#xff0c;你可以发送GET、POST、PUT、DELETE等请求&#xff0c;以及设置请求头、处理响应等。以下是一些使用curl进行HTTP请求的常见用法和示例。 1. 发送…

(十)IIC总线-PCF8591-ADC/DAC

文章目录 IIC总线篇起始&#xff0c;终止信号应答信号发送&#xff0c;读取数据IIC通讯规则 PCF8591-ADC-DAC篇特性一般说明地址Control byte&#xff08;控制字&#xff09;简单了解一下DAC电阻分隔链应用为王DAC的应用ADC的应用ADC采集特点ADC读模式 ADC现象演示DAC现象演示 …

八、Stm32学习-USART-中断与接收数据包

1.通信接口 全双工就是数据的收和发可以同时进行&#xff1b;半双工就是数据的收和发不能同时进行。 异步时钟是设备双方需要约定对应的波特率&#xff1b;同步时钟是设备双方有一根时钟线&#xff0c;发送或接收数据是根据这根时钟线来的。 单端电平是需要共GND&#xff1b;…

uniapp 打包成 apk(原生APP-云打包)免费

修改APP配置 根据需求&#xff0c;修改 manifest.json 配置&#xff0c;常见的修改有&#xff1a; 应用名称&#xff0c;应用版本名称&#xff0c;应用版本号 升级版本时&#xff0c;应用版本名称和应用版本号必须高于上一版的值 应用图标 点浏览选择png格式的图片后&#x…

【VPN技术】简述几种常见VPN技术并比较其异同点

VPN技术是一种可以在公共网络上建立加密通道的技术&#xff0c;通过这种技术可以使远程用户访问公司内部网络资源时&#xff0c;实现安全的连接和数据传输。 下面以四种常见的VPN技术&#xff0c;分别介绍各自的特点和适用场景&#xff0c;然后进行异同点的比较。 PPTP&#x…

微信私域,如何实现高效回复客户消息?

随着微信用户数量的增加&#xff0c;人们的需求也越来越多。其中有一项就是全天候及时回复消息&#xff0c;不让好友等待。当企业拥有多个微信号进行私域流量管理时&#xff0c;如何做到及时回复客户消息呢&#xff1f; 下面给大家分享高效回复客户消息的秘诀&#xff0c;帮助提…

highlight.js 实现搜索关键词高亮效果 ,显示匹配数量及切换显示功能

先看效果&#xff1a; 更新&#xff1a;增加切换显示 折腾了老半天&#xff0c;记录一下 注意事项都写注释了 代码&#xff1a; <template><div class"absolute-lt wh-full overflow-hidden p-10"><div style"width: 200px"><el-…

研究了Web版Photoshop,提升自己=提升价值

Adobe 发布了Web版 Photoshop&#x1f517;&#xff0c;它是使用 WebAssembly、web components、P3 颜色等 Web 技术构建的。本文就来研究一下网页版 Photoshop 上有趣又有用的 CSS 知识&#xff01; Photoshop 旧 Logo 首先&#xff0c;在浏览器控制台中使用了 Photoshop 的 …

【数字人】9、DiffTalk | 使用扩散模型基于 audio-driven+对应人物视频 合成说话头(CVPR2023)

论文&#xff1a;DiffTalk: Crafting Diffusion Models for Generalized Audio-Driven Portraits Animation 代码&#xff1a;https://sstzal.github.io/DiffTalk/ 出处&#xff1a;CVPR2023 特点&#xff1a;需要音频对应人物的视频来合成新的说话头视频&#xff0c;嘴部抖…

基于python的Hurst计算预测未来发展趋势(长时序栅格影像)

1.Hurst指数反映了时间序列长期记忆性的程度&#xff0c;即过去的信息对未来的影响程度。Hurst指数的取值范围为0到1之间&#xff0c;当Hurst指数等于0.5时&#xff0c;时间序列被认为是一种随机漫步&#xff0c;即具有随机性&#xff1b;当Hurst指数大于0.5时&#xff0c;时间…

JAVA基础学习笔记-day17-反射

JAVA基础学习笔记-day17-反射 1. 反射(Reflection)的概念1.1 反射的出现背景1.2 反射概述1.3 Java反射机制研究及应用1.4 反射相关的主要API1.5 反射的优缺点 2. 理解Class类并获取Class实例2.1 理解Class2.1.1 理论上2.1.2 内存结构上 2.2 获取Class类的实例(四种方法)2.3 哪些…

【MySQL】本地创建MySQL数据库详解

文章目录 下载MySQL安装重置密码本地连接 下载MySQL 下载网址&#xff1a;https://dev.mysql.com/downloads/mysql/ 安装 将下载好的压缩包解压到D盘。 在解压好的文件夹中创建my.ini文件。 将以下代码复制粘贴到创建好的my.ini文件中。注意修改文件路径。 [mysqld] #设置…

重生奇迹MU装备升级材料的获取

在重生奇迹MU中&#xff0c;装备升级需要使用各种材料&#xff0c;包括经验章、神秘石、宝石、元素石等。以下是各种材料的获取方法。 经验章&#xff1a;经验章是装备升级的基础材料&#xff0c;可以通过打怪掉落、任务奖励、商城购买等方式获得。建议玩家们多参加游戏中的活…