比较经典的题目,剑指offer上也有,各种面试笔试宝典上也都有
好像也不算太难,核心的代码只有几行,但是往往需要我们重点考虑的其实是在各种特殊输入的考虑上。
#include <iostream>
#include <cstdio>
using namespace std;
float atof(const char * arr)
{
const char * index = arr;
float result = 0;
int fcount = 0;
int Sign = 1;
bool HavePoint = false;
while(' ' == *index)
{
index++;
}
if ('-' == *index)
{
Sign = -1;
index++;
}
if ('+' == *index)
{
index++;
}
while(*index != '\0')
{
if ('.' == *index)
{
HavePoint = true;
break;
}
if (*index <= '9' && *index >= '0')
{
result = (result * 10) + (*index - '0');
}
index++;
}
// cout << result << endl;
index++;
while(*index != '\0' && HavePoint)
{
if (*index <= '9' && *index >= '0')
{
fcount++;
int temp = fcount;
float ftemp = (*index- '0');
while(temp--)
{
ftemp = ftemp / 10.0;
}
result = result + ftemp;
}
index++;
// cout << result << endl;
}
return Sign * result;
}
int atoi(const char * arr)
{
const char * index = arr;
int result = 0;
int Sign = 1;
while(' ' == *index)
{
index++;
}
if ('-' == *index)
{
Sign = -1;
index++;
}
if ('+' == *index)
{
index++;
}
while(*index != '\0')
{
if (*index <= '9' && *index >= '0')
{
result = (result * 10) + (*index - '0');
}
index++;
}
return Sign * result;
}
int main()
{
char arr1[20] = "+123.456";
char arr2[20] = "0.456";
char arr3[20] = "123";
char arr4[20] = "-123.456";
char arr5[20] = " -1a23.4b56";
char arr6[20] = "sd";
char arr7[20] = "";
char *arr8;
char arr9[20] = " -1a234b56";
// atof(arr);
// arr = "123.456";
cout << atof(arr1) << endl;
cout << atof(arr2) << endl;
cout << atof(arr3) << endl;
cout << atof(arr4) << endl;
cout << atof(arr5) << endl;
cout << atof(arr6) << endl;
cout << atof(arr7) << endl;
cout << atof(arr8) << endl;
cout << atoi(arr8) << endl;
cout << atoi(arr9) << endl;
// printf("%f\n", atof(arr));
return 0;
}
注意
需要了解出题人的意思,到底对于输入输出是什么要求。出题人的要求未必和C标准库的一致,
1.比如输入“-343sadf23”的话,输出是啥,输出-34423和-343显然是不一样的,
2.“++1”,这个怎么算,算1还是非法输入?
3.整数溢出的问题,32位下int的最大值是2147483647,超过之后怎么处理,按最大值还是置0?
这些如果是在面试的话一定要问清楚面试官。如果是在LeetCode上的话就比较好办了,因为可以在提交之前自己放数据测试,它会给出你程序的结果和它后台得到的结果。
上面的代码在LeetCode上无法通过,非常棒的是,LeetCode给出了没有通过的测试用例,“-+1”期望的输出是0,而我由于代码中分别判断了-和+,所以给出了1的错误结果。
关于溢出,LeetCode是按照取INT_MAX处理,剑指offer上使用long long所以我先用long long做,做完比较是否超出。然而没想到LeeetCode居然用超过long long的数据测试,于是我把测是否超出放到循环中,这才AC。。。
下面是AC的代码
int myAtoi(char* str) {
const char *temp = str;
int sign = 1;
long long result = 0;
if (str == NULL)
return -1;
if (*str == '"')
return -2;
while(*temp == ' ')
temp++;
if (*temp == '-')
{
sign = -1;
}
if (*temp == '+' || *temp == '-')
{
temp++;
}
while(*temp != '\0')
{
if (*temp >= '0' && *temp <= '9')
{
result = *temp - '0' + result * 10;
temp++;
if(result > INT_MAX)
{
result = sign == 1 ? INT_MAX : INT_MAX + 1;
break;
}
}
else
break;
}
return sign * result;
}
在C标准库中,先定义了一个_Stoul函数,然后所有的转换函数会调用这个函数,由于它是个通用函数,实现起来比较复杂, 我也没搞清楚。。。
下面贴一下蒋方勤的代码
int atoi(const char *str)
{
int num = 0;
int sign = 1;
const int len = strlen(str);
int i = 0;
while(str[i] == ' ' && i < len)
i++;
if (str[i] == '+')
i++;
if (str[i] == '-')
{
sign = -1;
i++;
}
for (; i < len; ++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_MAX : INT_MAX;
num = num * 10 + str[i] - '0';
}
return num * sign;
}
他对溢出的判断很有意思,是判断之前结果是否小于最大值的10分之1,且现在的位数是否大于最大值的个位。
这篇博客讨论了LeetCode上的String to Integer (atoi)问题,强调在解决此类问题时需要注意输入输出的要求,如特殊字符处理、溢出情况以及不同输入的边界条件。作者指出,面试中必须明确这些问题,并分享了在LeetCode上遇到的测试用例导致的错误及解决方案。代码实现中,对于溢出的判断采用了特定策略,最终实现了AC(Accepted)。
503

被折叠的 条评论
为什么被折叠?



