[LeetCode]String to Integer (atoi)atof,itoa

这篇博客讨论了LeetCode上的String to Integer (atoi)问题,强调在解决此类问题时需要注意输入输出的要求,如特殊字符处理、溢出情况以及不同输入的边界条件。作者指出,面试中必须明确这些问题,并分享了在LeetCode上遇到的测试用例导致的错误及解决方案。代码实现中,对于溢出的判断采用了特定策略,最终实现了AC(Accepted)。

比较经典的题目,剑指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,且现在的位数是否大于最大值的个位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值