1、题目描述:
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,
则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−2^31, 2^31 − 1]。
如果数值超过这个范围,请返回 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31) 。
2、示例
示例 1:
输入: "42"
输出: 42
示例 2:
输入: " -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
示例 4:
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
因此无法执行有效的转换。
示例 5:
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
因此返回 INT_MIN (−231) 。
3、解答
class Solution {
public int myAtoi(String str) {
//去除起始的空白字符
String numStr=trimHeadSpace(str);
//无有效字符返回0
if(numStr==null||numStr.isEmpty()){
return 0;
}
//起始字符不合法返回0
if(!isValideStart(numStr.charAt(0))){
return 0;
}
//提取转换数字符号
int flag=getNumberFlag(numStr.charAt(0));
//定义转换迭代起始下标
int index=(isDigital(numStr.charAt(0)))?0:1;
//转换结果初始化
int ret=0;
//迭代处理每一位
for(;index<numStr.length()&&isDigital(numStr.charAt(index));index++){
int increment=numStr.charAt(index)-'0';
//先进行溢出判断
if(testOverFlow(flag,ret,increment)){
ret=flag>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
return ret;
}
//数字并入
ret=ret*10+increment;
}
//返回结果
return ret*flag;
}
//溢出判断
private boolean testOverFlow(int flag,int current,int increment){
int realValue=flag*current;
return realValue>Integer.MAX_VALUE/10
|| (realValue==Integer.MAX_VALUE/10&&increment>7)
|| realValue<Integer.MIN_VALUE/10
|| (realValue==Integer.MIN_VALUE/10&&increment>8);
}
private boolean isDigital(char c){
return c>='0'&&c<='9';
}
private String trimHeadSpace(String str){
if(str==null||str.isEmpty()){
return null;
}
int index=0;
for(;index<str.length();index++){
if(str.charAt(index)!=' '){
break;
}
}
return str.substring(index,str.length());
}
private boolean isValideStart(char c){
return isDigital(c)||c=='+'||c=='-';
}
private int getNumberFlag(char c){
if(isDigital(c)||c=='+'){
return 1;
}
if(c=='-'){
return -1;
}
return 0;
}
}
注:本题目的核心在于溢出判定,原理见《整数反转》
4、复杂度
假设字符串长度为n,生成输入的子串,所以空间复杂度为O(n),循环遍历每一位,所以时间复杂度位O(n).
题目出处:leetcode网站