您的位置:首页 > 其它

8. String to Integer (atoi)

2015-06-24 13:33 225 查看
在解答这道题目的时候,有一些需要很注意的点,如下:

1. 输入字符串s可能为空。
2. 前面可能会有空格
3. 处理可选的+、-标记
4. 计算真正的整数值
5. 处理min和max

写粘贴上我的代码:

class Solution {
public:
int myAtoi(string str) {
long long result = 0;
int i, len = (int)str.length(), flag = 1; // flag是标记是负数还是正数
bool firstNotBlank = false; // <span style="font-family: Arial, Helvetica, sans-serif;">firstNotBlank的作用是标记首个非空字符是否已经出现</span>
for (i=0; i<len; i++) {
if (!firstNotBlank && str.at(i) == ' ') {
continue;
} else if (!firstNotBlank && (str.at(i) == '+' || str.at(i) == '-')) {
firstNotBlank = true;
if (str.at(i) == '-') {
flag = -1;
}
} else if (str.at(i) >= '0' && str.at(i) <= '9') {
firstNotBlank = true;
result = result*10 + (str.at(i)-'0')*flag;
if (flag == 1 && result > INT32_MAX) { // 判断是否越界
return INT32_MAX;
} else if (flag == -1 && result < INT32_MIN) {
return INT32_MIN;
}
} else {
break;
}
}
return (int)result;
}
};

http://www.programcreek.com/2012/12/leetcode-string-to-integer-atoi/上面的java代码如下,严格说来其代码是有一点小问题的,比如说result的类型为double,但是在算法运行过程中,result可能会越界。另外因为java可以调用trim函数,去掉前后的空格,所以其算法比上面的算法要简单明了。
public int atoi(String str) {
if (str == null || str.length() < 1)
return 0;

// trim white spaces
str = str.trim();

char flag = '+';

// check negative or positive
int i = 0;
if (str.charAt(0) == '-') {
flag = '-';
i++;
} else if (str.charAt(0) == '+') {
i++;
}
// use double to store result
double result = 0;

// calculate value
while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) <= '9') {
result = result * 10 + (str.charAt(i) - '0');
i++;
}

if (flag == '-')
result = -result;

// handle max and min
if (result > Integer.MAX_VALUE)
return Integer.MAX_VALUE;

if (result < Integer.MIN_VALUE)
return Integer.MIN_VALUE;

return (int) result;
}


思路:

细节实现题,这种题主要考察corner case是否都考虑全了,需要和面试官多交流。这里需要考虑的有:

1. 起始空格、非数字字符。

2. 正负号。

3. 0为数字中的最高位

4. overflow/underflow

5. 末尾非数字字符

根据以上枚举的特殊情况,判断的流程如下:

0. 用一个unsigned long long ret来记录结果,用bool isNeg记录正负。

1. 跳过所有起始空格,找到第一个非空格字符c0

(a) c0非数字字符(包括\0)也非正负号,返回0。

(b) c0为+或-,若下一个字符c1为数字,用isNeg记录下正或负,并移到c1。否则返回0。

(c) c0为数字,则更新ret

2. 经过1已经找到了第一个数字字符,以及结果的正负。此时只需要逐个扫描后面的数字字符,并更新ret即可。终止的条件有以下几个:

(a) 扫到一个非数字字符,包括\0和空格。返回ret

(b) ret已经超出int的范围,返回相应的INT_MIN/INT_MAX

这几条都想清楚后,代码写起来就不容易错了。

class Solution {
public:
int atoi(const char *str) {
bool isNeg = false;
unsigned long long ret = 0;

// skip leading white spaces
while(*str==' ') str++;

// first none white space char must be +- or digit
if(!isdigit(*str) && *str!='+' && *str!='-') return 0;

// for +-, next char must be digit
if(*str=='+' || *str=='-') {
if(!isdigit(*(str+1))) return 0;
if(*str=='-') isNeg = true;
str++;
}

while(isdigit(*str)) {
ret = ret*10 + (*str - '0');
if(ret>(unsigned long long)INT_MAX)
return isNeg ? INT_MIN : INT_MAX;
str++;
}
return isNeg ? -(int)ret : (int) ret;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: