首页 > 代码库 > String to Integer (atoi)

String to Integer (atoi)

Implement atoi to convert a string to an integer.

Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.

Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

比较考验逻辑的一道题,需要考虑很多特殊样例,提交了10+次才过。

个人思路:分情况讨论,用if语句排除掉各种错误。

int myAtoi(char* str) {  long long sum = 0;//开大点,用来判断是否在int的取值范围  bool flag = true;//判断数字前是否有正负号,数字是正是负  bool track = true;//判断数字前是否有空格  bool track2 = true;//判断数字中间是否有空格  for (int i = 0; str[i] != \0; i++) {    if ((str[i] == + || str[i] == -) && track) { track = false; track2 = false; if (str[i] == -) flag = false; continue; }    else if (str[i] == + || str[i] == -) return 0;    if (str[i] >= 0 && str[i] <= 9 && flag) {       sum += str[i] - 0;      if (sum > 2147483647) { return 2147483647; }      track2 = false;    }    else if (str[i] >= 0 && str[i] <= 9 && !flag) {       sum -= str[i] - 0;      if (sum < -2147483648) { return -2147483648; }      track2 = false;    }    else if (str[i] ==   && track2) continue;    else return sum;    if (str[i + 1] != \0 && str[i + 1] >= 0 && str[i +1] <= 9) sum *= 10;  }  return sum;}

分析:3ms过的,速度很快,但是相当于是自己造轮子,下面有个C++的解法超简单。

其他思路:

1.  部分利用库的C写法 by deepak50

int myAtoi(char* s){     int i=0,sign,max=0;     long long val=0;     for(i=0;isspace(s[i]);i++)         ;//isspace函数,当s[i]是空白符(空白符指空格、水平制表、垂直制表、换页、回车和换行符)时,返回非零。
     sign = (s[i]==-) ? -1:1;//判断正负,最后相乘。

if(s[i] == + || s[i] == -) i++;
for(val=0;isdigit(s[i]);i++) { //判断是否是数字,返回非零值,反之返回零。

val
=10*val+(s[i]-0);

if(val > INT_MAX) { max=1; break; }
}
if(max) { if(sign==1) return INT_MAX; else return INT_MIN; }

return val*sign;
}

2. 完全利用库的C++写法 by kybconnor

  istringstream sin(str);  int ans=0;  sin>>ans;  return ans;

利用istringstream类的特性恰好符合本题要求的特点,非常抖机灵。(补充学习 <sstring>)

3. 部分利用库的C++写法 by morning_color

int myAtoi(string str) {    long result = 0;    int indicator = 1;    for(int i = 0; i<str.size();)    {        i = str.find_first_not_of( );        if(str[i] == - || str[i] == +)            indicator = (str[i++] == -)? -1 : 1;        while(0<= str[i] && str[i] <= 9)         {            result = result*10 + (str[i++]-0);            if(result*indicator >= INT_MAX) return INT_MAX;            if(result*indicator <= INT_MIN) return INT_MIN;                        }        return result*indicator;    }}

4. 一个神奇的方法去判断溢出 by 

int atoi(const char *str) {    int sign = 1, base = 0, i = 0;    while (str[i] ==  ) { i++; }    if (str[i] == - || str[i] == +) {        sign = 1 - 2 * (str[i++] == -);     }    while (str[i] >= 0 && str[i] <= 9) {        if (base >  INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - 0 > 7)) { //接近溢出时,数字最后一位不得为8, 9            if (sign == 1) return INT_MAX;            else return INT_MIN;        }        base  = 10 * base + (str[i++] - 0);    }    return base * sign;}

在那个if语句中,对INT_MIN的溢出判断是有逻辑问题的,但是输出没问题。因为当恰好为INT_MIN时,if判断其为溢出,返回的还是INT_MIN,所以测试能过。

还有就是7,最好改为INT_MAX % 10,更具有普遍性。

 

总结:欲想成其事,必先利其器。熟练运用各种常见库是非常有必要的。比如INT_MAX, INT_MIN,判断是否是空白符号这些,自己写简直蠢爆。

String to Integer (atoi)