您的位置:首页 > 职场人生

[面试] 算法(一) —— Str2Int

2016-03-26 17:30 477 查看
“123” ⇒ 123

不允许使用 atoi 等其他类似的库函数;

一种 naive 版:

int str2int(const char* str)
{
if (str == NULL)
return 0;
int num = 0;
while (*str != '0')
num = num * 10 + *str++ - '0';
return num;
}


其实代码的核心逻辑在(num = num*10 + *str - ‘0’;):

{[ (0*10 + k1) ] * 10 + k2 }*10 + k3 = 100*k1 + 10*k2 + k3

这段代码的核心问题在未考虑空指针 NULL,空字符串”“、正负号、溢出、非法输入(0-9以外的其他输入)等方方面面的测试用例;

这里的一个问题在于,我们将空指针 NULL、空字符串”“,溢出、非法输入,统统返回为 0,可是如果遇到真正的”0”,怎么办?

设置一个全局的状态变量(g_status),初始化为 Invalid,直到能够遍历到字符串的结尾(
'\0'
)为 Valid。所以,最终的判断逻辑是,如果结果为 0,且 g_status 为 Valid,则为真正的 0,如果结果为0,但 g_status 为 Invalid,则为非法输入。

enum Status { Valid, Invalid};
int g_status = Valid;

int Str2Int(const char* str)
{
g_status = Invalid;
long long num = 0;
bool minus = false;
if (str != NULL && *str != '\0')
{
if (*str == '+')
{
++str;
}
else if (*str == '-')
{
minus = true;
++str;
}
if (*str != '\0')
num = Str2IntHelper(str, minus);
}
return (int)num;
}
long long Str2IntHelper(const char* digit, bool minus)
{
long long num = 0;
int flag = minus ? -1:1;
while (*digit != '\0')
{
if (*digit >= '0' && *digit <= '9')
{
num = num*10+flag*(*digit - '0');
if ( (!minus && num > 0x7fffffff) || (minus && num) < (signed int)0x80000000)
return 0;
++str;
}
else
return 0;
}
if (*str == '\0')
// 遍历到字符串的末尾
g_status = Valid;
return num;
}


客户端调用(测试):

int num = Str2Int("+123");
if (num == 0 && g_status == Invalid)
非法输入
else
输出即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: