首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Leetcode: String to Integer (atoi)

Leetcode: String to Integer (atoi)
EN

Code Review用户
提问于 2017-12-11 06:27:11
回答 1查看 1.7K关注 0票数 3

解出这个:

实现atoi将字符串转换为整数。atoi的要求:在找到第一个非空白字符之前,函数首先会根据需要丢弃尽可能多的空白字符。然后,从这个字符开始,取一个可选的正负号,后面跟着尽可能多的数字,并将它们解释为一个数值。字符串可以在构成整数的字符之后包含其他字符,这些字符被忽略,对此函数的行为没有任何影响。如果str中的第一个非空格字符序列不是有效整数,或者由于str为空或仅包含空白字符而不存在该序列,则不执行转换。如果无法执行有效的转换,则返回一个零值。如果正确的值超出了可表示值的范围,则返回INT_MAX (2147483647)或INT_MIN (-2147483648)。

解决方案:

首先检查字符串是否为null,然后检查是否为空,如果为true,则返回0。继续迭代字符串,直到我们到达第一个非空空格字符。

从这个位置,我们检查第一个字符是'+‘还是'-’。如果是这样的话,我们将迭代器移动一步,并注意布尔isNegative中的符号。

从当前位置,只要该字符是整数,我们就将其添加到solution中,同时每次检查是否溢出。我们继续遍历字符串,直到到达一个非整数字符并返回solution

代码语言:javascript
复制
class Solution {
    boolean isNegative = false;
    int i = 0; // string iterator position

    public int myAtoi(String str) {
        int solution = 0;

        if (str == null || str.isEmpty()) {
            return 0;
        }
        while (i < str.length() && str.charAt(i) == ' ') {
            i++; // discard leading whitespace
        }
        checkSign(str);
        for (; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                int prev = solution; // keep solution from last iter to check for overflow
                solution = solution*10; // move number left one position
                solution = solution+(str.charAt(i)-'0'); // increase solution by curr integer
                if (isOverflow(prev, solution)) {
                    if (isNegative) {
                        return Integer.MIN_VALUE;
                    }
                    return Integer.MAX_VALUE;
                }
            } else {
                return signSolution(solution); // we've reached a non-integer character before end of string
            }
        }
        return signSolution(solution); // last character of string is an integer
    }

    boolean isOverflow(int prev, int curr) {
        // prev = value at last iteration
        // curr = value after current iteration
        if (curr/10 == prev) {
            return false;
        }
        return true;
    }

    void checkSign(String str) {
        if (str.charAt(i) == '+') {
            i++;
        } else if (str.charAt(i) == '-') {
            isNegative = true;
            i++;
        }
    }

    int signSolution(int solution) {
        if (isNegative) {
            return solution*-1;
        }
        return solution;
    } 
  }
EN

回答 1

Code Review用户

回答已采纳

发布于 2017-12-11 17:48:17

通常,当将String解析为int时,人们希望它是一个静态方法。

必须创建一个类来进行计算有点麻烦,然后您需要担心同步(如果这个类在多个线程之间共享,会发生什么情况?)

代码语言:javascript
复制
boolean isOverflow(int prev, int curr) {
    // prev = value at last iteration
    // curr = value after current iteration
    if (curr/10 == prev) {
        return false;
    }
    return true;
}

这个方法已经是一个很好的静态选择,它只依赖于它的两个输入来判断是否发生溢出。

代码语言:javascript
复制
boolean isNegative = false;
int i = 0; // string iterator position

void checkSign(String str) //uses i and isNegative

int signSolution(int solution) //uses isNegative

这些问题稍微复杂一些,int signSolution(int solution)只需接受另一个参数:static int signSolution(int solution, boolean isNegative)

需要将void checkSign(String str)作为myAtoI方法的一部分,或者重写一些

如果我们将+视为空白,那么它只需要担心如何处理-

代码语言:javascript
复制
static boolean checkSign(String str, int i)
{
    return str.charAt(i) == '-';
}

checkSign(str);的调用将改为if(checkSign(str)) i++;

保持一致。你在混合类似结构的循环

代码语言:javascript
复制
while (i < str.length() && str.charAt(i) == ' ')
    i++;
[...]
for (; i < str.length(); i++) {
    [...]
}

它们都可以是循环,也可以是同时循环,但是混合是出乎意料的。

代码语言:javascript
复制
for(; i < str.length() && str.charAt(i) == ' '; i++);
[...]
for(; i < str.length(); i++)
{
    [...]
}

vs

代码语言:javascript
复制
while(i < str.length() && str.charAt(i) == ' ')
    i++;
[...]
while(i < str.length())
{
    [...]
    i++;
}

检查“空格”当前只检查空格。

不使用str.charAt(i) == ' ',您可以将复杂的功能卸载到另一种方法(以后更容易更改)。

代码语言:javascript
复制
static boolean isWhiteSpace(char c)
{
    return c == ' ';
}

然后,如果您想包括所有的空白(和+以及上面提到的)

代码语言:javascript
复制
static boolean isWhiteSpace(char c)
{
    return Character.isWhitespace(c) || (c == '+');
}

if(bool) return true; else return false;的实例与return bool;的实例相同

代码语言:javascript
复制
if (curr/10 == prev) {
        return false;
}
return true;

可以简化为

代码语言:javascript
复制
return curr / 10 != prev;

OptionalA:

另一种检查溢出的方法是将输出存储为一个长,并检查它是否溢出。

代码语言:javascript
复制
public static int myAtoI(String str)
{
    long solution = 0;
    [...]
}

private static isOverflow(long num)
{
    return num == (int)num;
}

OptionalB:

如果值是负数,则可以减去值,而不是添加值,然后翻转结果

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/182519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档