把字符串转换成整数

news2024/11/27 4:37:18

题目:把字符串转换成整数

思路:

如果对于一般规则的数字“字符串”转化为数字都很容易,比如:

对于“123456”可以利用如下代码进行转化:

string str="123456";
int ans = 0;
for (int i=0; i<str.size(); ++i) 
{
    ans = ans * 10 + (str[i] - '0');
}

问: str[i]-'0'是什么意思?

在 C++ 中,char 类型的字符可以转换为数字类型,其中 '0' 字符对应的十进制 ASCII 码值为 48,'1' 对应的是 49,以此类推。当我们用一个 char 类型的变量或字符数组的元素存储一个数字字符时,我们可以通过减去 '0' 来将其转换为数字(即转换为该数字对应的 int 类型)。

举个例子,对于字符数组 str,str[i] 表示 str 数组中第 i 个元素所对应的字符。如果 str[i] 存储的是字符 '8',那么 str[i] - '0' 的值就是 8 。由于 '0' 字符固定是 48,所以根据 ASCII 码表,'8' 的十进制 ASCII 码值为 56,因此表达式 str[i] - '0' 就等于 56 - 48 = 8,即代表数字 8。

=>‘数字'-'0'=(int)数字

问:ans = ans * 10 + (str[i] - '0')是什么意思?

ans=0+1

ans=1*10+2=12

ans=12*10+3=123

...

int的范围为 [-2^{31},2^{31-1}]
如果超过了这两个范围该怎么办?
其实也很简单,首先判断这个数的正负,如果正数,超过了INT_MAX,就设置为INT_MAX,如果是负数,首先我们不考虑负号,如果超过了INT_MAX+1, 则就置为INT_MAX+1, 最后再根据正负号,来加负号。

//判断正负
bool neg = str[i]=='-' ? true : false;
//判断该下标对应的字符是否是数字
//如果是,就i=i
//如果否,就i=i+1,往后挪一位
i = isdigit(str[i]) ? i : i+1;

long long ans = 0L; // 因为INT_MAX+1超过了int的范围

while (i < len && isdigit(str[i])) {
    ans = ans * 10 + (str[i++]-'0');

    if (!neg && ans > INT_MAX) {
        ans = INT_MAX;
        break; //因为此处以为最大值,所以直接break
    }
    if (neg && ans > 1L + INT_MAX) {
        ans = 1L + INT_MAX;
        break;
    }
}

long long ans = 0L;是什么意思?

0L 表示长整型数字 0字符 L 是为了告诉编译器这是一个 long 类型的字面量。通常情况下,在使用 long 类型的字面量时,将其写成 0L 或者 0l(小写的 L)来区分于普通的整型字面量 0。这是因为一些编译器在处理无修饰的整数字面量时可能会发生整数溢出和类型转换等问题。所以为了确保程序可以正确地工作,我们更倾向于在使用 long 类型的字面量时加上修饰符 L。 

 if (!neg && ans > INT_MAX) {
        ans = INT_MAX;
        break; //因为此处以为最大值,所以直接break
    }

这段代码表示在 ans 大于 INT_MAX (整数类型的最大值)时,将 ans 赋值为 INT_MAX。同时,由于已经找到最大值,所以程序可以退出循环并终止后续的操作,即使用 break 语句来结束循环。在 if 语句的条件判断中,'!' 表示逻辑取反运算符,所以 !neg 的结果为 true 表示正数,并且 ans 大于 INT_MAX,进入条件成立块执行该代码。

if (neg && ans > 1L + INT_MAX) {
        ans = 1L + INT_MAX;
        break;
    }

这段代码进行了一个整数溢出的判断,如下所述:

  • 如果要转换的整数为负且其绝对值比INT_MAX+1还大,则会发生下溢出(negative overflow),即数值过小导致运算结果不能正确表示。这是因为在int类型的范围内只能存储一定范围的整数值(符号位用来表示正负),如果超出了该范围,则会表现为异常行为,例如截断或重载。
  • 为了避免下溢出的情况,我们采取了特殊处理,这里将ans设置成1L + INT_MAX,其中的1L为long类型的1,表示额外使用了一个bit位,可用于解决下溢出的问题。然后使用break语句退出循环,此时已找到最长整数子串并完成了相应的处理,不需要继续迭代后续字符。

总的来说,该段代码是为了解决边界问题而设计的,以保证函数正确性及稳定性。

最后再考虑一些特殊情况即可。

class Solution
{
public:
    int StrToInt(string str)
    {
        const int len = str.length();
        if (len == 0) return 0;
        int i = 0;
        while (i < len && str[i] == ' ') { ++i; } // 排除开头的空格
        if (i == len) return 0;
        if (!isdigit(str[i]) && str[i] != '+' && str[i] != '-') return 0;
        bool neg = str[i] == '-' ? true : false;
        i = isdigit(str[i]) ? i : i + 1;
        long long ans = 0L;

        while (i < len && isdigit(str[i]))
        {
            ans = ans * 10 + (str[i++] - '0');

            if (!neg && ans > INT_MAX)
            {
                ans = INT_MAX;
                break;
            }
            if (neg && ans > 1L + INT_MAX) {
                ans = 1L + INT_MAX;
                break;
            }
        }
        if (i != len) return 0; // 不要此处,就是atoi()库函数的实现
        return !neg ? static_cast<int>(ans) : static_cast<int>(-ans);
    }
};

这段代码实现了将字符串转换成整数的功能,其流程如下:

  1. 首先判断输入字符串是否为空串,如果是,则直接返回0;
  2. 接着排除开头的空格符;
  3. 如果剩余字符中不是数字字符也不是正号或负号,则认为输入不合法,返回0;
  4. 确定正负性,如果是负数,则标记neg为true;
  5. 从第一位开始,取出连续的整数子串,并将其转换成整数。如果超过int类型能表示的范围,进行相应处理;
  6. 最后根据正负标志返回对应整数。

这段代码完善地考虑了各种异常情况,比如前导空格、加减号位置、多余字符等,使用了long long类型来避免数据溢出等问题。同时,代码结构清晰,变量名具有描述性,易于理解和调试。

 

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

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

相关文章

Elesticesearch

1. 概述 应用场景&#xff1a; 给你一个巨大的文档数据&#xff0c;文档中存储着许多非结构化的数据&#xff0c;如下&#xff1a; {“id” : “1”, “name” : “佛山张学友”, “age” : “15”}, {“name” : “广州周润发”, “height” : “182”}, …中间有10000万行……

ABAP 二分法查找与SORT排序

需求场景 需要对内表排序&#xff0c;按降序排列&#xff0c;获取第一行&#xff1b;二分法查找需要的数据 我按照降序排列后&#xff0c;获取到了第一行&#xff0c;但是通过二分法查找没有获取到 二分法查找 二分查找&#xff0c;对排序数组通过二分区间排除的方法进行快速…

最好用的六款虚拟机软件,赶紧收藏

在日常工作和学习中,我们常常需要在一台电脑上运行多个操作系统,以便进行软件测试、开发、学习以及实验等任务。虚拟机软件就是一种崭新的技术,它可以在一台电脑上运行多个操作系统,为用户提供了更高效、安全、稳定和智能化的工作和学习环境。今天我为大家介绍6款优秀的虚拟…

k8s安装监控工具metrics-server

我们需要监控cpu和内存的使用率.以便提供硬件资源的申请采购建议. 也方便我们知道运行负荷, 而不是糊里糊涂出了问题再去解决或者工具自动解决了而我们不知道, 话说回来集群的好处就是低成本的达到高性能, 性能不去监控就有点太不专业了. 但, k8s居然不自带监控工具 https://ku…

了解hiberfil.sys文件:计算机休眠模式的背后

简介: hiberfil.sys是Windows操作系统中的一个文件&#xff0c;它通常存储在计算机的根目录下&#xff0c;用于保存休眠模式下的内存映像。当您将计算机置于休眠模式时&#xff0c;Windows会将所有正在运行的程序和数据保存到hiberfil.sys文件中&#xff0c;然后关闭计算…

SAP MRP例外信息解释

SAP中MRP的例外信息&#xff0c;一共分为八类&#xff0c;下面是所有例外信息的解释 第一类&#xff1a; 69&#xff1a;BOM组件可能是递归的&#xff0c;即自己的子集中包括了自己。 02&#xff1a;订单创建日期在过去&#xff0c;可能是没有及时处理&#xff0c;这个建议表…

【Python爬虫实战】汽车城最好的十款车,第一名竟是这款车...Python教你一键采集二手车数据信息实现数据可视化展示哦~(附视频教程)

前言 驾考不易&#xff0c;天天早起去练车&#xff0c;无论烈日还是下雨&#xff0c;通通都在室外进行&#xff0c;但想要拿证&#xff0c;一定要坚 持不懈的去练车。 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或…

【Docker】2、Docker 基本操作【镜像操作】

目录 一、镜像相关命令(1) 镜像名称格式(2) 常见镜像命令 二、从 DockerHub 拉取镜像案例三、镜像导出和导入案例四、拉取 Redis 镜像练习 一、镜像相关命令 (1) 镜像名称格式 &#x1f50b; 镜像名称一般由两部分组成&#xff1a;[repository]:[tag] &#x1f50b; 若没有指…

Java每日一练(20230428)

目录 1. 搜索旋转排序数组 &#x1f31f;&#x1f31f; 2. 用栈实现队列 &#x1f31f; 3. x 的平方根 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 搜索旋转排序…

机器学习:基于PCA对人脸识别数据降维并建立KNN模型检验

基于PCA对人脸识别数据降维并建立KNN模型检验 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&…

nodejs+vue+springboot+python电影放映厅购票网站

&#xff08;结合完成了以上的基本目标之后&#xff0c;能够帮助管理人员对系统的方便管理&#xff0c;从而能够为管理员节省时间&#xff0c;给了用户极大的方便。系统中的数据要存储于数据库当中&#xff0c;能够通过SQL代码把数据库中的数据取出&#xff0c;映射到实体类中&…

Classic AUTOSAR专题 | 存储模块简介

往期小怿向各位小伙伴介绍了Classic AUTOSAR的OS模块&#xff0c;相信看过的小伙伴对Classic AUTOSAR的OS已经有基本的认知了&#xff0c;本期我们将继续介绍Classic AUTOSAR专题之存储模块的知识。 目录 1.AUTOSAR存储模块概述 2.NvM功能简介 3.应用层SWC如何访问NvM 4.小…

在Docker中安装并运行Redis(纯步骤)

在Docker中安装并运行Redis容器实例 此文章只有操作步骤&#xff0c;没有原理解释&#xff0c;只供学习时提醒安装步骤。 安装并运行可以分为四步 第一步&#xff1a;安装redis镜像 从远程仓库上查询redis的相关版本信息&#xff08;可以省略&#xff09; docker search red…

mac环境VSCode 配置C++,并写Hello World

安装VSCode&#xff0c;点击下载链接&#xff0c;下载Mac版本的vscode。安装“C extension for VS Code”&#xff0c;在扩展 (⇧⌘X)中搜索c&#xff0c;并安装确保CLANG安装成功。在mac的终端下输入clang --version&#xff0c;如果安装成功会打印相关信息&#xff0c;未成功…

《基于深度卷积神经网络的光电容积脉搏图血管老化评估》阅读笔记

目录 一、论文摘要 二、十个问题 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一…

亚马逊云科技帮助创新成长企业云端构建、全球化布局及规模化增长

4月13日&#xff0c;以“加速创新&#xff0c;成就未来”为主题的亚马逊云科技创新成长中国行深圳论坛圆满举行。会上亚马逊云科技宣布&#xff0c;将围绕创新成长企业的三大业务需求——云上创新、出海拓展、业务加速&#xff0c;提供行业聚焦、技术支撑、伙伴扶持、人才培养四…

Dubbo 高级特性 (3)

其实Dubbo的官方文档非常强大&#xff0c;里面的各种各样的标签都会介绍到&#xff0c;但是最新版的官方文档好像找不那么多详细的使用了。在此&#xff0c;我推荐一篇博客&#xff0c;里面列举的也蛮全面的&#xff0c;可以参考&#xff1a; dubbo配置参考手册_dubbo使用手册_…

前端叹了口气,并表示谣言止于智者

如何评价此次“前端已死”言论引起的轩然大波&#xff1f; 从市景角度来看&#xff0c;那就是“一传十&#xff0c;十传百&#xff0c;越传越离谱”。 从新闻角度来看&#xff0c;是“传播扭曲效应”&#xff0c;指信息传播的链条越长&#xff0c;信息越失真。 用《乌合之众…

博客系统[Java]

目录 一.准备工作 二.实现数据库代码(JDBC) 1.创建数据库/表结构>数据库设计 2.封装数据库(Model) 1>创建DBtil封装数据库连接操作 2>创建实体类-->表示一条记录 3>封装针对数据的增删改查 三.博客列表页 1.约定前后端 2.编写服务器代码 3.编写客户端…

【笔试强训选择题】Day7.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…