LeetCode #String to Integer (atoi)#
自己写一个atoi. 其实之前都没怎么调用过这个库函数. 具体性能也不怎么知道.
自己写的时候感觉有个版本比题目要求还好,但是不能被接受, 于是就改改改
话说AC的感觉真爽...
我尽量把代码写的紧凑...
"""
Programmer : EOF
Date : 2015.04.01
File : string_to_integer.py
"""
class Solution():
INT_MAX = 2147483647
INT_MIN = -INT_MAX - 1
def is_digital(self, c) :
if len(c) == 0 :
return False
if '9' >= c and c >= '0':
return True
return False
def atoi(self, string) :
length = len(string)
if length == 0 :
return 0
num = 0
found_tag = False
positive = True
blank_cleared = False
for i in range(0, len(string)):
if blank_cleared is False and string[i] == ' ':
"Do nothing"
elif blank_cleared is True and string[i] == ' ':
break
elif string[i] == '+' or string[i] == '-':
blank_cleared = True
if found_tag is False :
found_tag = True
if string[i] == '-' :
positive = False
else:
return 0
elif self.is_digital(string[i]) is True:
blank_cleared = True
num *= 10
num += int(string[i]) - int('0')
else:
break
if positive is False :
num *= -1
if num > INT_MAX :
return INT_MAX
elif num < INT_MIN :
return INT_MIN
else :
return num
s = Solution()
print s.atoi("+ 123hello45")
print s.atoi("-12345")
print s.atoi("12345")
print s.atoi(" +004500")
print s.atoi(" +0 04500")
思路也很简单, 字符串如果有空格的话就清楚空格,如果开头的空格都清除过了, 已经遇到字符或数字, 再遇到空字符我们认为这个字符串是错误的.不符合要求, return 0
默认的数值为正数. 我用了个变量positive来标记符号. 多次遇到正负符号说明是错误的字符串. return 0 所以我用了个found_tag来标记是否我们已经找了正负符号说明, 重新遇到我们认为字符串错误.
最后做好数据范围处理, 不要超过整数范围.
好, 我们来看看皓神的作品:
// Source : https://oj.leetcode.com/problems/string-to-integer-atoi/
// Author : Hao Chen
// Date : 2014-06-18
/**********************************************************************************
*
* 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.
*
*
* Requirements for atoi:
*
* 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. If the correct value
* is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648)
* is returned.
*
**********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define INT_MIN (-2147483647 - 1)
#define INT_MAX 2147483647
int atoi(const char *str) {
if (str==NULL || *str=='\0'){
return 0;
}
int ret=0;
for(;isspace(*str); str++);
bool neg=false;
if (*str=='-' || *str=='+') {
neg = (*str=='-') ;
str++;
}
for(; isdigit(*str); str++) {
int digit = (*str-'0');
if(neg){
if( -ret < (INT_MIN + digit)/10 ) {
return INT_MIN;
}
}else{
if( ret > (INT_MAX - digit) /10 ) {
return INT_MAX;
}
}
ret = 10*ret + digit ;
}
return neg?-ret:ret;
}
int main()
{
printf("\"%s\" = %d\n", "123", atoi("123"));
printf("\"%s\" = %d\n", " 123", atoi(" 123"));
printf("\"%s\" = %d\n", "+123", atoi("+123"));
printf("\"%s\" = %d\n", " -123", atoi(" -123"));
printf("\"%s\" = %d\n", "123ABC", atoi("123ABC"));
printf("\"%s\" = %d\n", " abc123ABC", atoi(" abc123ABC"));
printf("\"%s\" = %d\n", "2147483647", atoi("2147483647"));
printf("\"%s\" = %d\n", "-2147483648", atoi("-2147483648"));
printf("\"%s\" = %d\n", "2147483648", atoi("2147483648"));
printf("\"%s\" = %d\n", "-2147483649", atoi("-2147483649"));
return 0;
}
最后我准备翻番标准库的实现的, 但是翻看之后感觉太"库化"了. 感觉各种难看. 就算了...