代码之家  ›  专栏  ›  技术社区  ›  sigjuice

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

  •  0
  • sigjuice  · 技术社区  · 15 年前

    下面是一个简单的函数,它将字符串转换为整数。

    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 回复  |  直到 15 年前
        1
  •  2
  •   Barry Kelly    15 年前

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

    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);
    }
    
        2
  •  1
  •   Kyle Rosendo    15 年前

    好吧,您可以对使用该功能的人隐藏该功能。所以您将有一个名为 int str2int(char *str) 这将呼叫 int str2int(char *c, int *i) 此后。

    我过去就是这样做的。

        3
  •  0
  •   Aif    15 年前

    我想你可以用 horner scheme 为了不保留任何“我”。

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

    int str2int (char* str)
    {
        if (*str+1)
        {
            return 10*str2int(str+1)+(*str-'0');
        }
        return 0;
    }
    
        4
  •  0
  •   Chris Lutz    15 年前

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

    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的幂。

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