Leetcode练习 #8 String to Integer (atoi)

来源:互联网 发布:mac pro 13寸高清壁纸 编辑:程序博客网 时间:2024/06/03 14:59



题目简析:实现 字符-àint整数的转换,题意很简单,实现方法也是多种多样,扫描整个字符串、用栈、队列都是可以的,不过这题的要点其实不是把字符换成整数这一步,而是对于一些非法输入等情况的处理。

 

       输入接受一个字符串,根据一些提交测试来看,接受的字符串可能的情况,是包括0个及以上的正负号、空格、数字以及其他非法符号的随意排列组合,下面列举一些例子

  

“123”

  123”

 123   

 1   23 ”

“-123  

  -123  

“+ 123  

 +12 3  

“+-134  

“+ +123  

“ 123+ + 12  

“&%124”



       根据一些非法字符串总结出来,合法字符串应该包括以下条件:

(1)数字串前面允许0个,或1+-号,不允许连续正负号或者正负号以外的其他符号(如连续的+-号,%&@*/等符号)


(2)数字与数字间有任何及任意数量非数字字符都是非法的,非数字字符前面的数字串若合法则输出,但非数字字符后面的数字串无论合法非法,均不输出(如“124 45”或“124%&45”输出124,但“&&1234  54”属于非法数字串)


(3)正负号与数字之间不能有空格,但是在带符号数字串的正负号前面、或者无符号的数字串前面可以有空格


(4)数字范围要在int范围(-2147483648~2147483647)内,假如超出范围,只输出最大or最小值

(如:“3333333333333333—>2147483647  -333333333333333—>-2147483648 


(5)不能为空字符串、或仅有符号的字符串


(6)支持整数,故小数点也属于非法字符,参考第2点。


对于以上要求,除了超出数字范围的第四点以外,其他数字串若非法则输出数字0,否则输出对应的数字(int类型)


字符串转换思路: 

       经过对合法字符串要求的总结分析,在进行转换之前,首先应该排除非法字符串,以及对字符串进行提取的预处理,因为从第三点看来,并不是字符串所有的数字都是需要转换的。

          第一步在字符串首端的检查上,简单排除0长度字符串、1长度无数字字符串。


        第二步是对空格的处理,根据第23点,我们可以总结为——在遇到任何非空字符前,空字符都是可以忽略的,但是遇到非空字符后,任何空字符都属于非法字符,与其他非数字字符都可以立即判定字符串非法。因此对字符串进行解析之前,我们要跳过前端的空格。

      

       第三步是找到一个合法的数字串并截取,根据第1点看是否可能存在一个合法的数字串开端,若有则截取至第一个非法字符(第2点),将之保存(栈或者队列或者用变量记录位置均可)。


       第四步是将之转化为数字,我用的方法是将每一位进行幂运算并累加(sum+=bit*pow,pow110100……1000000000),并判断正负号情况。

    

       最后一步是处理溢出问题,对于int范围而言,采取累加的方法是有可能导致溢出的。这里判断的方法因人而异,我的方法是判断累加过程是否产生正负变化(我是先累加完才赋予正负,因此累加的结果必定是整数),以及待累加的幂的大小(int范围是-2147483648~2147483647,因此超过1000000000这个数量级的待累加幂意味着溢出要发生),这个方法仅供参考。

其他的一些细节比如溢出后值的输出,稍微有点取巧的地方,其实用简单的if else也能解决,不一定要像我那样偷懒。


下面就附上代码吧


class Solution {public:    int myAtoi(string str) {        int pow=1;        int sum=0;        stack<int> stk;        int flag=1;        bool overflow=false;        if(str.length()==0)            return 0;        else if(str.length()==1)            return (str[0]>='0' && str[0]<='9')*(str[0]-'0');                int blank=0;        while(1){            if(str[blank]==' ')                blank++;            else                break;                    }        int i=(str[blank]=='+' || str[blank]=='-')+blank;        while(i<str.length()){            if(str[i]>='0' && str[i]<='9')                stk.push(str[i]-'0');            else                break;            i++;                  }                        while(!stk.empty()){            sum=sum+stk.top()*pow;            if(sum<0 || pow > 1000000000){                sum=2147483647;                overflow=true;                break;            }            pow*=10;            stk.pop();        }        if(str[blank]=='-')            flag=-1;        if(overflow)            return flag*sum+(flag-overflow)/2;        else            return flag*sum;    }};


Submission Result: Accepted

Runtime: 0 ms


题目链接:https://leetcode.com/problems/string-to-integer-atoi/description/