需求:
实现atoi这个函数,将一个字符串转换为整数。如果没有合法的整数,返回0。如果整数超出了32位整数的范围,返回INT_MAX(2147483647)如果是正整数,或者INT_MIN(-2147483648)如果是负整数。
思路:
该题目较为复杂,需要分类讨论多种情况。题意为将字符串中出现的第一个完整的整数返回,包括"+10" "-10" " 54 abd" "5.6"等情况。所以应该考虑空格、正负号的问题等。另外,对于以0开头的数字没有进行考虑,但测试集中并没有此类数据,因此也通过了测评。
算法步骤:
1、当字符串为null或者长度是0,肯定是不合法数,直接返回0,否则执行步骤2
2、对字符串进行去除两端空格的操作,然后进行分析,执行步骤3
3、如果2操作之后的字符串是空的,那么是不合法数,直接返回0,否则进行步骤4
4、遍历字符串,获取字符串第一个字符ch0,创建字符缓冲区,用来存储有效数字。如果是ch0数字,即ASCII码在'0'和'9'之间,那么执行步骤5,如果是'+',那么执行步骤6,如果是'-',那么执行步骤7,其余的直接执行步骤8
5、将ch0添加到缓冲区中,继续遍历字符串,如果是有效的数字,就添加到缓冲区中,否则跳出,进行处理。因为这个数值是非负数,所以可以直接和最大值进行比较即可,鉴于字符串转成数值有大小限制,所以先判断缓冲区的长度,因为Integer的最大值的长度是10,所以如果缓冲区长度大于10,肯定溢出了,所以直接返回最大值,如果没有那么使用字符串转long型数进行转换,然后和最大值进行比较,如果没有超过范围就直接返回(int)long值,如果超过了,就直接返回最大值
6、只有当字符串的长度大于1并且'+'后面是数字才有可能是合法数,这是一个判断条件,如果满足,则将'+'和后面的数字添加到缓冲区,然后继续遍历字符串,将有效数字添加到缓冲区,直到遇到非数字字符,跳出处理。对缓冲区的长度进行判断,如果大于11,那么肯定溢出,直接返回最大值,否则,使用字符串转long型数进行转换,和最大值进行比较,如果没有超过范围,直接返回(int)long值,否则返回最大值
7、只有当字符串的长度大于1并且'-'后面是数字才有可能是合法数,这是一个判断条件,如果满足,则将'-'和后面的数字添加到缓冲区,然后继续遍历字符串,将有效数字添加到缓冲区,直到遇到非数字字符,跳出处理。对缓冲区的长度进行判断,如果大于11,那么肯定溢出,直接返回最小值,否则,使用字符串转long型数进行转换,和最小值进行比较,如果没有超过范围,直接返回(int)long值,否则返回最小值
8、如果第一个有效字符既不是数字也不是'+' '-'号,那么就不是合法数,直接返回0
代码:
public class Solution {
/*
* @param str: A string
* @return: An integer
*/
public int atoi(String str) {
// write your code here
//如果字符串是null或者长度为0,直接返回0
if(str == null || str.length() == 0)
{
return 0;
}
//去除字符串两端的空格
str = str.trim();
//如果去除空格后为空,就直接返回0
if(str.isEmpty())
{
return 0;
}
//获取字符串第一个字符,只有第一个字符是数字或者+-号的时候才有可能是合法数
char ch0 = str.charAt(0);
//创建字符缓冲区,用来存储有效数字
StringBuilder sb = new StringBuilder();
//当第一个字符是数字时
if(ch0 >= '0' && ch0 <= '9')
{
sb.append(ch0);
for(int i = 1; i < str.length(); i++)
{
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9')
{
sb.append(ch);
}
else
{
break;
}
}
//如果缓冲区长度大于10,肯定溢出(不考虑第一个数字是0的情况)
if(sb.length() > 10)
{
return Integer.MAX_VALUE;
}
else
{
long num = Long.parseLong(sb.toString());
if(num > Integer.MAX_VALUE)
{
return Integer.MAX_VALUE;
}
else
{
return (int)num;
}
}
}
//如果第一个字符是'+'
if(ch0 == '+')
{
//只有当字符串长度大于1并且'+'后面是数字时才有可能是合法数
if(str.length() > 1 && str.charAt(1) >= '0' && str.charAt(1) <= '9')
{
sb.append(ch0).append(str.charAt(1));
for(int i = 2; i < str.length(); i++)
{
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9')
{
sb.append(ch);
}
else
{
break;
}
}
//如果长度大于11,肯定溢出(不考虑第一个数字是0的情况)
if(sb.length() > 11)
{
return Integer.MAX_VALUE;
}
else
{
long num = Long.parseLong(sb.toString());
if(num > Integer.MAX_VALUE)
{
return Integer.MAX_VALUE;
}
else
{
return (int)num;
}
}
}
}
//如果第一个字符是'-'
if(ch0 == '-')
{
//只有当字符串长度大于1并且'-'后面是数字时才有可能是合法数
if(str.length() > 1 && str.charAt(1) >= '0' && str.charAt(1) <= '9')
{
sb.append(ch0).append(str.charAt(1));
for(int i = 2; i < str.length(); i++)
{
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9')
{
sb.append(ch);
}
else
{
break;
}
}
//如果缓冲区长度大于11,肯定溢出(不考虑初始数字是0的情况)
if(sb.length() > 11)
{
return Integer.MIN_VALUE;
}
else
{
long num = Long.parseLong(sb.toString());
if(num < Integer.MIN_VALUE)
{
return Integer.MIN_VALUE;
}
else
{
return (int)num;
}
}
}
}
//其余情况,均返回0
return 0;
}
}