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

“123” ⇒ 123

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

一种 naive 版:

int str2int(const char* str)
{
    if (str == NULL)
        return 0;
    int num = 0;
    while (*str != '\0')    // while (*str != 0), '\0' == 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 {[ (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)
                       // 0x7fff ffff 表示正的最大值
                       // 0x8000 0000 表示负的最小值
                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
    输出即可
    原文作者:Inside_Zhang
    原文地址: https://blog.csdn.net/lanchunhui/article/details/50987876
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞