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

来源:互联网 发布:Java编程思想豆瓣 编辑:程序博客网 时间:2024/04/29 11:11

“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    输出即可
0 0