递归地将字符串转换为整数?

时间:2009-08-28 06:48:18

标签: c recursion

这是一个将字符串转换为整数的简单函数。

int str2int(char *str)
{
    int ret = 0;
    char *c;

    for (c = str; (*c != '\0') && isdigit(*c); ++c)
        ret = ret*10 + *c - '0';

    return ret;
}

作为一个练习,我想编写一个执行相同操作的递归函数。这就是我想出来的。

int str2int2(char *c, int *i)
{
    if (*c == '\0' || !isdigit(*c))
        return *i;

    *i = *i * 10 + *c - '0';

    return str2int2(c + 1, i);
}

.
.
int i = 0;
.
... str2int2(str, &i);

有没有办法在不使用额外int*参数的情况下编写递归函数?

4 个答案:

答案 0 :(得分:2)

当然,这很容易,但你需要编写两个函数,一个带累加器,如下所示:

int str2int_rec(char *c, int accum)
{
    if (!c || !*c || !isdigit(*c))
        return accum;

    return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}

int str2int(char *c)
{
    return str2int_rec(c, 0);
}

答案 1 :(得分:1)

好吧,你可以隐藏使用该功能的人的功能。因此,您将拥有一个名为int str2int(char *str)的函数,此后将调用int str2int(char *c, int *i)

这就是我过去的做法。

答案 2 :(得分:0)

我认为您可以使用horner scheme以便不保留任何“我”。

你必须扭转字符串(是的,退出丑陋)然后你可以简单地使用:

int str2int (char* str)
{
    if (*str+1)
    {
        return 10*str2int(str+1)+(*str-'0');
    }
    return 0;
}

答案 3 :(得分:0)

一种方法可能涉及将数字的长度作为参数传递,以便我们可以有效地向后阅读:

int strtoi(char *c, size_t l)
{
    return l ? c[l-1] - '0' + 10 * strtoi(c, l - 1) : 0;
}

然后这样称呼:

int i = strtoi("432", 3);

或者:

char *c = "432";
int i = strtoi(c, strlen(c));

但是,打扰一个字符串的长度并不总是最佳的。另外,如果一个字符串在数字后面有字符,我们必须手动考虑它,因为这个函数不会为我们做。我们不能(不应该)在我们的函数中使用strlen()来避免必须传递参数,因为这可能导致每次重新计算字符串长度的相当大的减速。当然,必须有一种方法可以从一开始就做到这一点,即使我们必须带出重型火炮:

int strtoi(char *c)
{
    if(!isdigit(*c)) return 0;
    int i = strtoi(c + 1);
    return i + pow(10, (int)(log(i + 1)/log(10)) + (i != 0)) * (*c - '0');
}

不,那个(int)演员不是可选的。基本上,所有这些数学计算我们需要根据最后一次递归调用返回的数字乘以当前数字所需的10的幂。

我知道这可能是一个学习练习,但递归并不是最终的所有编程。在某些语言中,对于某些任务来说,包括我自己在内的一些人称之为美丽,但从外观来看,这不是其中之一。