leetcode刷题记录——字符串转换整数(atoi)

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

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

读入字符串并丢弃无用的前导空格

检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。

读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。

将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。

如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。

返回整数作为最终结果。

注意:

本题中的空白字符只包括空格字符 ' ' 。

除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

来源:力扣(LeetCode)链接:https://leetcode.cn/problems/string-to-integer-atoi

佬的思路

通过设定i移动字符下标,t为对应数,sign为判断正负,解析为整数用的是ASCII码来获取的,再设定边界条件输出。

C语言:

作者:exciting-shamirbdu链接:https://leetcode.cn/problems/string-to-integer-atoi/solution/cyu-yan-shi-xian-dai-ma-ji-jian-ban-by-e-gxsg/

intmyAtoi(char*s){

inti,sign=0,t=0;

for(i=0;s[i]==' ';i++) continue;

if(s[i]=='-'||s[i]=='+') sign=s[i++]=='-'?1:0;

for(;s[i]>='0'&&s[i]<='9'&&t>-2147483648;i++){

if((t==-214748364&&s[i]>'8')||t<-214748364) t=-2147483648;

elset=t*10-(s[i]-'0');

}

if(sign) returnt;

return (t==-2147483648)?2147483647:-t;

}

//时间 0ms,空间5.5MB

Java:

这个问题其实没有考察算法的知识,模拟的是日常开发中对于原始数据的处理(例如「参数校验」等场景),如果面试中遇到类似的问题,应先仔细阅读题目文字说明和示例,有疑惑的地方和需要和面试官确认,在编码的时候需要耐心和细心地调试。

其实很多时候,业务需求就是类似这样的问题,工作中如果遇到:

1、有现成的工具和类库需尽量使用,因为它们是性能更优,且经过更严格测试,是相对可靠的;2、能抽取成工具类、工具方法的尽量抽取,以突出主干逻辑、方便以后代码复用;3、不得不写得比较繁琐、冗长的时候,需要写清楚注释、体现逻辑层次,以便上线以后排查问题和后续维护。

在这里我罗列几个要点:

根据示例 1,需要去掉前导空格;

根据示例 2,需要判断第 1 个字符为 + 和 - 的情况,因此,可以设计一个变量 sign,初始化的时候为 1,如果遇到 - ,将 sign 修正为 -1;

判断是否是数字,可以使用字符的 ASCII 码数值进行比较,即 0 <= c <= '9';

根据示例 3 和示例 4 ,在遇到第 1 个不是数字的字符的情况下,转换停止,退出循环;

根据示例 5,如果转换以后的数字超过了 int 类型的范围,需要截取。这里不能将结果 res 变量设计为 long 类型,注意:由于输入的字符串转换以后也有可能超过 long 类型,因此需要在循环内部就判断是否越界,只要越界就退出循环,这样也可以减少不必要的计算;

由于涉及下标访问,因此全程需要考虑数组下标是否越界的情况。

特别注意:

1、由于题目中说「环境只能保存 32 位整数」,因此这里在每一轮循环之前先要检查乘以 1010 以后是否溢出,具体细节请见编码。

2、Java 、Python 和 C++ 字符串的设计都是不可变的,即使用 trim() 会产生新的变量,因此我们尽量不使用库函数,使用一个变量 index 去做遍历,这样遍历完成以后就得到转换以后的数值。

作者:liweiwei1419链接:https://leetcode.cn/problems/string-to-integer-atoi/solution/jin-liang-bu-shi-yong-ku-han-shu-nai-xin-diao-shi-/来源:力扣(LeetCode)

publicclassSolution {

publicintmyAtoi(Stringstr) {

intlen=str.length();

// str.charAt(i) 方法回去检查下标的合法性,一般先转换成字符数组

char[] charArray=str.toCharArray();

// 1、去除前导空格

intindex=0;

while (index<len&&charArray[index] ==' ') {

index++;

}

// 2、如果已经遍历完成(针对极端用例 " ")

if (index==len) {

return0;

}

// 3、如果出现符号字符,仅第 1 个有效,并记录正负

intsign=1;

charfirstChar=charArray[index];

if (firstChar=='+') {

index++;

} elseif (firstChar=='-') {

index++;

sign=-1;

}

// 4、将后续出现的数字字符进行转换

// 不能使用 long 类型,这是题目说的

intres=0;

while (index<len) {

charcurrChar=charArray[index];

// 4.1 先判断不合法的情况

if (currChar>'9'||currChar<'0') {

break;

}

// 题目中说:环境只能存储 32 位大小的有符号整数,因此,需要提前判:断乘以 10 以后是否越界

if (res>Integer.MAX_VALUE/10|| (res==Integer.MAX_VALUE/10&& (currChar-'0') >Integer.MAX_VALUE%10)) {

returnInteger.MAX_VALUE;

}

if (res<Integer.MIN_VALUE/10|| (res==Integer.MIN_VALUE/10&& (currChar-'0') >-(Integer.MIN_VALUE%10))) {

returnInteger.MIN_VALUE;

}

// 4.2 合法的情况下,才考虑转换,每一步都把符号位乘进去

res=res*10+sign* (currChar-'0');

index++;

}

returnres;

}

publicstaticvoidmain(String[] args) {

Solutionsolution=newSolution();

Stringstr="2147483646";

intres=solution.myAtoi(str);

System.out.println(res);

System.out.println(Integer.MAX_VALUE);

System.out.println(Integer.MIN_VALUE);

}

}

总结:

这道题题目给得很充分,我开始想的是用指针移动到数字,可是想了半天怎么也不知道如何转字符串,看了大佬的代码后,才知道用ASCII码来来解析,发现自己怎么这么蠢,后面的限定范围自己弄得不太懂,临界值处一直失败。int类型在内存中占用了4个字节,也就是32位。int类型是有符号的,因此,32位并不会全部用来存储数据,使用最高位来存储符号,最高位是0,提示数据是正数,最高位是1,表示数据是负数,使用其他的31位来存储数据。

收获:

ASCII码

学习链接:

ASCII码-https://www.asciim.cn/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值