49字符串转换为整数

题目描述

将一个字符串转换成一个整数,字符串不是一个合法的数值则返回 0,要求不能使用字符串转换整数的库函数。

Iuput:
+2147483647
1a33
Output:
2147483647
0

思路分析

代码逻辑简单,0号位判断是否有+、-符号,其他位判断是否为数字,有字母则返回0。
主要问题在边界判断和输入数据判断上。特别是溢出判断

  • 有效。输入的字符串检测是否有效。常规检验。
  • 正负号。输入的字符串中,正数可以带+号也可以为纯数字。最后返回时需要根据-号判断。
  • 溢出。输出int类型数的边界判断。主要是处理最小负数和判断数值越界溢出。

最小负数

int类型的边界为 -2147483648—2147483647,最大正数的绝对值小于最小负数绝对值。在常规做法中,我们用正数表示结果,最后一步才根据已知将结果取负,所以最终结果会出错。

解决方案

将+,-转为int类型,当符号为+时,标志为1;符号为-时,标志为-1。将符号位参与运算过程中。
eg. value=value10+digit ==> value=value10+isNegtive*digit

数值越界

数值越界即大于2147483647,小于-2147483648。

解决方案

在每次循环时,通过INT_MAX/10的值提前判断是否越界。
eg.

  • 当 value > INT_MAX/10 时,说明扩大10倍后,value 必将越界。
  • 当 value == INT_MAX/10 时,说明扩大10倍后,value 可能越界,也可能不越界,需要利用当前的加数 digit 做进一步的判断:正数是当 digit > 7 时,越界;复数是当 digit > 8 时,越界。
  • 当 value < INT_MAX/10 时,本轮循环必不越界。

正负数越界判断合并

设置正负标记位isNegative,变量overValue记录当前值和INT_MAX/10的差,因为INT_MAX/10为正数,当当前值为负数时,用isNegative转为正数。
overValue = isNegative*value - INT_MAX/10
则overValue>0,越界;overValue<0,不越界;overValue==0时,isNegative=1,digit>7越界;isNegative=-1,digit>8越界。
为方便操作,将-1、1转换为0、1:(isNegative+1)/2+digit > 8时,数值越界。
综上所述,

overValue = isNegative*value - INT_MAX/10
          + (((isNegative+1)/2 + digit > 8) ? 1:0);

当overValue>0时,数值将会越界,反之不会。

代码实现

public static int StrToInt(String str) {
    int length = str.length();
    int isNegative = 1, overValue = 0;
    int digit = 0, value = 0;

    if (length == 0) {
        return 0;
    }
    char[] chars = str.toCharArray();

    int index = 0;
    if (chars[0] == '-') {
        isNegative = -1;
        index = 1;
    } else if (chars[0] == '+') {
        index = 1;
    } else {
        index = 0;
    }

    while (index < length) {
        digit = chars[index] - '0';
        //overValue用于判断此轮循环是否过界,>0过界,<0安全
        overValue = isNegative * value - Integer.MAX_VALUE / 10 +
                (((isNegative + 1) / 2 + digit > 8) ? 1 : 0);
        if (digit < 0 || digit > 9) {
            return 0;
        } else if (overValue > 0) {
            return 0;
        }
        value = value * 10 + isNegative * digit;
        index++;
    }

    return value;
}
发布了118 篇原创文章 · 获赞 8 · 访问量 3718

猜你喜欢

转载自blog.csdn.net/qq_34761012/article/details/104458608