分析
原題連結
這題歷史悠久,早在 30 年前 K&R C 語言 習題裡就出現過了,但小弟 submit n 次才成功。因為這題有個陷阱是解題系統會傳入超過 INT_MAX(2147483647),小於 INT_MIN(-2147483648) 的數值字串,系統希望「參數 > INT_MAX」 時傳回 INT_MAX,「參數 < INT_MIN」時傳回 INT_MIN,如果傻傻的照抄 K&C 習題解答,得到的是 overflow 的結果,當然就被 reject 了。
這題歷史悠久,早在 30 年前 K&R C 語言 習題裡就出現過了,但小弟 submit n 次才成功。因為這題有個陷阱是解題系統會傳入超過 INT_MAX(2147483647),小於 INT_MIN(-2147483648) 的數值字串,系統希望「參數 > INT_MAX」 時傳回 INT_MAX,「參數 < INT_MIN」時傳回 INT_MIN,如果傻傻的照抄 K&C 習題解答,得到的是 overflow 的結果,當然就被 reject 了。
個人採用的策略很簡單,既然傳入的是 int,那我用 long long (64bits) 運算不就避開超過 INT_MAX 或小於 INT_MIN 時無法判別的情形了嗎?
Source Code
int myAtoi(char* str) {
if(str == 0)
return 0;
while(*str == ' ')
++str;
if(*str == 0)
return 0;
char prefix = 0;
if(*str == '-' || *str == '+'){
prefix = *str++;
}
long long result = 0;
for(; *str != 0; ++str){
if(*str >= '0' && *str <= '9'){
result = result*10 + (*str - '0');
if(prefix != '-'){
if(result > 2147483647) return 2147483647;
}else{
if(result > 2147483648) return -2147483648;
}
}else{
break;
}
}
return (prefix == '-' ? -result : result);
}
另外一種策略是每次運算前(上述程式 Line#19),先判斷這次是不是會爆掉,這樣可以避免使用 64bits 整數,但缺點是效能上會大打折扣。//https://github.com/soulmachine/leetcode
int myAtoi(const char *str) {
int num = 0;
int sign = 1;
const int n = strlen(str);
int i = 0;
while (str[i] == ' ' && i < n) i++;
if (str[i] == '+') {
i++;
} else if (str[i] == '-') {
sign = -1;
i++;
}
for (; i < n; i++) {
if (str[i] < '0' || str[i] > '9')
break;
if (num > INT_MAX / 10 || (num == INT_MAX / 10 && (str[i] - '0') > INT_MAX % 10)) {
return sign == -1 ? INT_MIN : INT_MAX;
}
num = num * 10 + str[i] - '0';
}
return num * sign;
}
沒有留言:
張貼留言