LeetCode_Medium_8. String to Integer (atoi)

2019.1.24

题目描述:

Implement atoi which converts a string to an integer.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned.

Note:

  • Only the space character ' ' is considered as whitespace character.
  • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. If the numerical value is out of the range of representable values, INT_MAX (231 − 1) or INT_MIN (−231) is returned.

Example 1:

Input: "42"
Output: 42

Example 2:

Input: "   -42"
Output: -42
Explanation: The first non-whitespace character is '-', which is the minus sign.
             Then take as many numerical digits as possible, which gets 42.

Example 3:

Input: "4193 with words"
Output: 4193
Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.

Example 4:

Input: "words and 987"
Output: 0
Explanation: The first non-whitespace character is 'w', which is not a numerical 
             digit or a +/- sign. Therefore no valid conversion could be performed.

Example 5:

Input: "-91283472332"
Output: -2147483648
Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.
             Thefore INT_MIN (−231) is returned.

这题的题干真是冗长。。。看的晕头晕脑的,我总结一下:

输入一个字符串,只输出数字,遇到非数字字符就截断,遇到空格忽略,第一个非字符为符号时,保留符号。数字溢出时直接输出 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31),假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

我们设置一个flag用来表示正数还是负数,开头是空格就不断后移指针直到遇到第一个非空字符,若该字符是+或—,则flag相应变化,接着将后面连续的数字字符转换成数字,直到遇到非数字字符截断即可,切记在循环中进行比较是否超出边界,超出则直接返回边界,没超出则转换。

没什么思想值得细究,一顿if就完事了。

C++代码:

class Solution {
public:
    int myAtoi(string str) {
        if(str.size()==0) return 0;
        int flag=1,i=0;
        long long res=0;
        while(i<str.size()&&str[i]==' ') i++;
        if(str[i]=='+'||str[i]=='-'){
            if(str[i]=='+'){
                flag=1;
                i++;
            }
            else{
                flag=-1;
                i++;
            }
        }
        while(i<str.size()&&str[i]>='0'&&str[i]<='9'){
            res=res*10+str[i++]-'0';     
            if(flag==1&&res*flag>INT_MAX)
            return INT_MAX;
            if(flag==-1&&res*flag<INT_MIN)
            return INT_MIN;
        }
        return res*flag;
    }
};

Bug小记:

我之前思考的是,若是只比较与边界值的大小,则只需要进行一次比较最后已经转换成数字的res的最终值和边界值的大小,所以我代码如下:

class Solution {
public:
    int myAtoi(string str) {
        if(str.size()==0) return 0;
        int flag=1,i=0;
        long long res=0;
        while(i<str.size()&&str[i]==' ') i++;
        if(str[i]=='+'||str[i]=='-'){
            if(str[i]=='+'){
                flag=1;
                i++;
            }
            else{
                flag=-1;
                i++;
            }
        }
        while(i<str.size()&&str[i]>='0'&&str[i]<='9'){
            res=res*10+str[i++]-'0';     
        }
        if(flag==1&&res*flag>INT_MAX)
                return INT_MAX;
        if(flag==-1&&res*flag<INT_MIN)
                return INT_MIN;
        return res*flag;
    }
};

但是没有通过测试,没有通过的用例如下:

输入            "9223372036854775808"

输出            0

预期结果     2147483647

原因:long long的边界是9223372036854775807,该测试用例超出了long long的边界,所以出错了。

所以我试着改成了unsigned long long,本以为肯定OK了,没想到还是错了,不过这次没有通过的用例就特别奇怪了。

这次代码如下:

class Solution {
public:
    int myAtoi(string str) {
        if(str.size()==0) return 0;
        int flag=1,i=0;
        unsigned long long res=0;
        while(i<str.size()&&str[i]==' ') i++;
        if(str[i]=='+'||str[i]=='-'){
            if(str[i]=='+'){
                flag=1;
                i++;
            }
            else{
                flag=-1;
                i++;
            }
        }
        while(i<str.size()&&str[i]>='0'&&str[i]<='9'){
            res=res*10+str[i++]-'0';     
        }
        if(flag==1&&res*flag>INT_MAX)
                return INT_MAX;
        if(flag==-1&&res*flag<INT_MIN)
                return INT_MIN;
        return res*flag;
    }
};

没有通过的测试用例如下:

输入              "-"

输出              -2147483648

预期结果       0

按照输出结果,是在最后通过了if(flag==-1&&res*flag<INT_MIN)的判断从而输出了INT_MIN,但是这次我真的百思不得其解了,按理说,只有一个'-'的时候,上面一个while循环根本没有进入,res仍旧是0,0乘以-1还是0,应该是比INT_MIN大的,不可能通过该判断语句,况且,若是该测试用例不通过,那么,把这两个判断语句放入while循环内,应该也是一样不能通过的吧,但结果是放进while循环就可以通过

这个我真是不懂了,不知道是不是有什么思考的局限性或者缺陷,若是有大手子看到了这篇博客,恳请赐教!!万分感谢!

猜你喜欢

转载自blog.csdn.net/weixin_41637618/article/details/86620451