题目原文:
Implement atoi to convert a string to aninteger.
实现atoi。
题目虽然只有一句话,但是坑是不少,从填坑的步骤来看,大概会有如下几个隐藏的坑,或者说是硬性规定。
【醒目】下面的东西是经过多次提交发现了错误之后总结下来的。有剧透的嫌疑。推荐各位看官先尝试过后再来看。
1、 输入字符串允许有首空格,并且允许有复数个,排除掉。继续往下
2、 遇到字母返回0,否则继续往下。
3、 (至此,干扰字符都排除完了)遇到一个正/负符号(注意是一个),往4。否则往5.
4、 如果还是遇到正负号,此时就是(++/--/+-/-+)的情况了,非法,返回0。否则往5。
5、 (此时正负号已经合法了,扫描后续字符)正负号的后续字符会有3种:数字(往7);空格(往6);不是数字也不是空格(返回0)。
6、 这题允许正负号与数字之间存在空格,因此我们需要排除它。排除之后往7。
7、 (此时已经保证正负号后面接的都是数字了)和空格类似的是,数字允许有首零,并且允许多个。比如:000001和01和1是等价的。我们扫描完所有的0,只需要存下来一个:比如01就可以了。往8。
8、 扫描完了所有的0,存下了一个。那么后续的字符如果不是数字。(下标回移,指向最后一个0)。如果扫描完0之后,后续还有数字,扫描完后续的【连续】的数字并存下来。
(至此,已经取到合法的数字字符串了,如果没有走到这一步,说明输入是非法的,最后返回了0。)
9、 判断这个数字是否溢出,溢出则返回边界值。
10、转化成整型,设置负号。
上述10点就是解决方案了。
Leetcode的Accepted Solutions Runtime Distribution(截于5月上旬)
源码:(VS2013)如果需要提交leetcode只需要把函数中的代码复制过去即可。
#include <iostream>
#include <string>
using namespace std;
int myAtoi(string);
int main()
{
cout << myAtoi(" -00001190356x");
return 0;
}
int myAtoi(string s){
if (0 == s.size()) return 0;
if (1 == s.size()) return (s[0] - 48);
int fuhao = 1;
string::iterator iter = s.begin();//auto
//1、扫描开头的空格
//isspace();
while (' ' == *iter)
{
iter++;
}//开头空格扫描完了
//2、判断首字母
//isalpha();
//2、是字母 返回0
if (((*iter >= 'a') && (*iter <= 'z')) || ((*iter >= 'A') && (*iter <= 'Z')))
{
return 0;
}//经检测没有首字母
//3、正负号
if ('+' == *iter)
{
iter++;
}
else if ('-' == *iter)
{
fuhao = -1;
iter++;
}//正负号读取完毕
//4、非数字 返回0
// !isdigit();
if (!(*iter >= '0' && *iter <= '9'))
{
return 0;
}//没有非数字
//6、扫描空格,正负号和数字间允许空格
//isspace();
while (' ' == *iter)
{
iter++;
}//空格扫描完了
//7、扫描数字0
string res;
while ('0' == *iter)
{
res = '0';
iter++;
}//首0只需要存一个
//8、如果扫描完前置合法的0之后,刚好已经没有后续数字可以扫描了,迭代器前移,指向最后一个0
//那么这个情况的返回值是0
// !isdigit();
if (!(*iter >= '0' && *iter <= '9'))
{
iter--;
}
//8、如果扫描完前置合法的0之后,后面还有非0数字。
//设置指向第一个非零数字的迭代器。原本的迭代器向后扫描,获取一段连续的数字序列。
//isdigit();
string::iterator iterBefor = iter;//auto
while (iter != s.end() && *iter >= '0' && *iter <= '9')
{
iter++;
}//扫描完非零数字序列了
//8、把这个数字存下来
//这个数字序列只有一个数字
if (iterBefor == iter)
{
res += *iter;
}
//这个数字序列有不少数字
while (iterBefor != iter)
{
res += *iterBefor;
iterBefor++;
}
//数字序列转存完毕
//9、是否溢出int的范围
string maxInt = "2147483647";
if ((10 == res.size() && res > maxInt) || res.size() > 10)
{
if (1 == fuhao) res = "2147483647";//正数边界是2147483647
else res = "2147483648";//负数边界是-2147483648
//res = 1 == fuhao ? "2147483647" : "2147483648";
}
//10、把合法的string专为int
iter = res.begin();
int max = res.size();
int resInt = 0;
while (max > 0)
{
resInt += ((*iter) - 48) * (pow(10, max - 1));
max--;
iter++;
}
//10、设置符号
resInt *= fuhao;
return resInt;
}