[LeetCode][8]【学习日记】实现字符串转换整数 (atoi)函数

题目

8. 字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi
函数)。

函数 myAtoi(string s) 的算法如下:

  1. 读入字符串并丢弃无用的前导空格
  2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  4. 将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0。必要时更改符号(从步骤 2 开始)。
  5. 如果整数数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −2^31 的整数应该被固定为 −2^31 ,大于 2^31 − 1 的整数应该被固定为 2^31 − 1。
  6. 返回整数作为最终结果。

注意:

  • 本题中的空白字符只包括空格字符 ’ '。
  • 除前导空格或数字后的其余字符串外,请勿忽略任何其他字符。

示例 1:

输入:s = “42” 输出:42 解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
^ 第 1 步:“42”(当前没有读入字符,因为没有前导空格)
^ 第 2 步:“42”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^ 第 3 步:“42”(读入 “42”)
^ 解析得到整数 42。 由于 “42” 在范围 [−2^31, 2^31 − 1] 内,最终结果为 42。

示例 2:

输入:s = " -42" 输出:-42 解释:
^ 第 1 步:" -42"(读入前导空格,但忽视掉)
^ 第 2 步:" -42"(读入 ‘-’ 字符,所以结果应该是负数)
^ 第 3 步:" -42"(读入 “42”)
^ 解析得到整数 -42。 由于 “-42” 在范围 [−2^31, 2^31 − 1] 内,最终结果为 -42。

示例 3:

输入:s = “4193 with words” 输出:4193 解释:
^ 第 1 步:“4193 with
words”(当前没有读入字符,因为没有前导空格)
^ 第 2 步:“4193 with words”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^ 第 3 步:“4193 with words”(读入 “4193”;由于下一个字符不是一个数字,所以读入停止)
^ 解析得到整数 4193。 由于 “4193” 在范围 [−2^31, 2^31 − 1] 内,最终结果为 4193。

提示: 0 <= s.length <= 200 s 由英文字母(大写和小写)、数字(0-9)、’ ‘、’+‘、’-’ 和 ‘.’ 组成

思路

图片来自:https://leetcode.cn/leetbook/read/illustration-of-algorithm/lhqzq5/
在这里插入图片描述

  1. 去除前导空格
  2. 判断是否有符号
  3. 对后面的数字进行转 int 的操作,直到添加下一位可能溢出 或 遇到非数字 或 字符串结束

对于第三步的循环解释:

  1. j 小于字符串长度,且 str[j] 应为数字(204851r596)
  2. 以2147483647 / 10 == 214748364 为界。小于这个数则可以添加下一位数;等于这个数则需判断接下来的的一位数加上去是否溢出;大于则因为添加下一位数要先*10,所以必定溢出
    • 小于边界的情况:1234567891,有123456789 < 214748364,此时可以添加下一位数
    • 等于边界的情况:如 2147483648,则 214748364 = = 214748364,而添加8后必定溢出,所以输出溢出时的值;而 214748364 有 214748364 = = 214748364,但是添加 6 后也不溢出
    • 大于边界的情况:如3,000,000,000,3,000,000,00 > 214748364,因为添加下一位数要先*10,所以必定溢出;如20,000,000,000,在 9 位时 200,000,000 < 214748364,此时继续添加下一个 0,然后在下一轮循环中 2,000,000,000 就大于边界,再添加下一个 0 会溢出
  3. 总结:这道题的核心就是在添加下一位后会溢出时,立刻返回溢出值,否则就可以继续添加下一位

简洁解法:

参考 K 神的代码:https://leetcode.cn/leetbook/read/illustration-of-algorithm/lhqzq5/

class Solution {
public:int myAtoi(string str) {int i=0, symbol=1, ans=0;if(!str.length()) return 0;//空字符串while(str[i]==' '){//跳过前导空格++i;}if(str[i]=='-')symbol=-1;//遇到负号if(str[i]=='+' || str[i]=='-')++i;//有符号情况//开始处理数字部分//-2147483648 —— 2147483647for(int j=i; j<str.length() && isdigit(str[j]); ++j){if(ans>214748364 || (ans==214748364&&str[j]>'7')) return (symbol==1 ? INT_MAX : INT_MIN);ans = ans*10 + (str[j]-'0');}return ans*symbol;}
};

繁琐的解法

这种解法之所以繁琐:

  1. 前导空格和符号的处理放在了循环中
  2. 没有找到溢出的边界条件
class Solution {
public:int myAtoi(string str) {int symbol=1, ans=0, numBegin=0, i=0;bool overflow = false, haveFindNum = false;long maxInt = numeric_limits<int>::max();for(i=0; i<str.length(); ++i){if(str[i] == ' ' && !haveFindNum) continue;if(i+1<str.length() && (str[i]=='+' || str[i]=='-') && isdigit(str[i+1]) && !haveFindNum){if(str[i]=='+') symbol = 1;if(str[i]=='-') symbol = -1;numBegin = i+1;continue;}else if(!isdigit(str[i])) break;//下面处理str[i]为数字的情况haveFindNum = true;if(i-1<0) numBegin = 0;else if(i-1>=0 && str[i-1]==' ' && ans) numBegin = i;else if(!ans) numBegin = i;else if(i-2>=0 && str[i-2]=='0' && ans) numBegin = i;if(i-numBegin == 10){cout << numBegin;if(symbol == 1) return ((long)maxInt)*symbol;else return ((long)maxInt+1)*symbol;} long temp;temp = (long)ans * 10;if(temp > maxInt) {cout << "*";if(symbol == 1) return ((long)maxInt)*symbol;else return ((long)maxInt+1)*symbol;} ans *= 10;temp = (long)ans + str[i] - '0';if(temp > maxInt) {cout << "+";if(symbol == 1) return ((long)maxInt)*symbol;else return ((long)maxInt+1)*symbol;}ans += str[i] - '0';}return ans*symbol;}
};

结论

虽然一开始觉得这种题就是找一堆 if 进行判断,不断进行分类而已。但是仔细想想,能快速找到合适的边界条件就可以减少判断的分支个数,这方面能力还需要不断练习来提升。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ky10 server 离线编译安装nginx

代码地址 https://gitcode.net/zengliguang/linux_video_audio_nginx_proxy.git 下载代码 查看服务器上下载的代码 编译安装 进入代码路径 cd /root/linux_video_audio_nginx_proxy 执行离线编译安装脚本 source centos7_nginx_offline_comp_install.sh安装编译相关依赖 …

Java二级--操作题详解(1)

目录 1.第一套&#xff1a; 1.1 基本操作&#xff1a; 1.2 题解分析&#xff1a; 2.1 简单应用&#xff1a; 2.2 解题分析&#xff1a; 3.1 综合应用&#xff1a; 3.2解题分析&#xff1a; 1.第一套&#xff1a; 1.1 基本操作&#xff1a; 在考生文件夹中存有文件名为J…

SystemVerilog构造、包

包 包提供了一种共享不同构造的附加方式。他们的行为与VHDL包。包可以包含函数、任务、类型和枚举。的语法包是&#xff1a; package package_name; items endpackage : package_name 最终的package_name不是必需的&#xff0c;但它使代码更易于阅读。包是import命令在其他…

LeetCode每日一题 二叉树的最大深度(二叉树)

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,nul…

Kubernetes-3

Kubernetes学习第3天 Kubernetes-31、查看实时的cpu和内存消耗1.1、kubectl top node 2、卷的使用2.1、什么是卷&#xff1f;1. 解决数据持久性问题2. Kubernetes 中的卷抽象概念3. 共享数据示例4. Kubernetes 中的卷使用5. 不同类型的卷6. 灵活、可靠的数据管理 2.2、联想到do…

数据结构与算法-线性查找

引言 在计算机科学领域&#xff0c;数据结构和算法是构建高效软件系统的核心要素。今天我们将聚焦于最基础且广泛应用的一种查找算法——线性查找&#xff0c;并探讨其原理、实现步骤以及实际应用场景。 一、什么是线性查找&#xff1f; 线性查找&#xff08;Linear Search&am…

计算机考研❗️这些院校(含985)性价比巨高

✅厦门大学 (985) 不歧视双非&#xff0c;全靠实力&#xff0c;校园环境还贼美 ✅重庆大学 (985) 信息公开透明&#xff0c;复试抽签 ✅北京师范大学 (985) 不歧视本科出身&#xff0c;面试抽签答题。 ✅东南大学 (985) 保护第一志愿&#xff0c;复试抽签 ✅吉林大学 (…

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)

引言 其实C基础语法基本上已经学完&#xff0c;早就想开始写C的博客了&#xff0c;却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的&#xff0c;后来考虑了一下还是算了&#xff0c;等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…

进程:守护进程

一、守护进程的概念 守护进程是脱离于终端控制&#xff0c;且运行在后端的进程。&#xff08;孤儿进程&#xff09;守护进程不会将信息显示在任何终端上影响前端的操作&#xff0c;也不会被终端产生的任何信息打断&#xff0c;例如&#xff08;ctrlc&#xff09;.守护进程独立…

灵根孕育源流出,心性修持大道生

解法&#xff1a; 手动本地跑了一下1e9&#xff0c;显然超时。 然后预处理发现开不了这么大的数组。 肯定有规律&#xff0c;打表看看 代码如下 #include<iostream> #include<vector> #include<algorithm> #include<cmath> using namespace std; #…

七.AV Foundation 视频播放 - 图片进度条

引言 播放器的功能功能已经十分完善了&#xff0c;接下来我们给它添加一些提升用户体验的功能。当前市面上的主流播放器几乎都有一个非常友善的功能&#xff0c;用户在退拽进度条的时候可以看见进度条所处进度的视频画面&#xff0c;这对于用户来说是一种直观而且便捷的体验。…

vue2的element UI 表格单选

代码 this.$refs.multipleTable.toggleRowSelection(selection.shift(), false);multipleTable 是定义的表格的ref