【问题标题】:Recursive number function returns unexpected values [closed]递归数字函数返回意外值[关闭]
【发布时间】:2012-12-11 16:53:40
【问题描述】:

在广泛搜索将整数转换为视觉等效字符串的函数后,我一无所获,我决定自己编写。

函数“ascii”接受三个参数:要转换的整数、保存转换后整数的字符串和一个保留为 0 的计数器。

void ascii(int c, char str[], int k) {
    if (c <= 9) {
        str[k] = c + '0';
    }

    else if (c >= 10) {
        str[k] = c / 10 + '0';
        ascii(c % 10, str, k + 1);
    }
}

用个位数的数字测试这个函数并没有什么意外的结果,但是在更大的数字上,事情开始变得一团糟。 76变成“761”,765变成“|51”,7658变成“-81”。数字包含的数字越多,我对结果字符串的意义就越小。什么给了?

【问题讨论】:

  • 专业提示:使用 sprintf%d 说明符(更好的是,C99 中的 snprintf 或者如果您的编译器支持它)。
  • 为什么不能使用 sprintf?
  • 不是答案,但将 + 48 替换为 +'0' 会产生更易读的代码
  • ...而且更便携(至少在理论上)。
  • 如何输出?你会在末尾添加\0 吗?

标签: c string recursion int


【解决方案1】:

我相信问题出在这里:

else if (c >= 10) {
    str[k] = c % 10 + 48;
    ascii(c / 10, str, k + 1);
}

算术运算被反转了。生成的数组必须在之后反转(来自不同的函数,它将问题中的函数作为助手调用),并且它必须以 '\0' 字符结尾。

或者,您可以以相反的顺序将结果复制到输出数组中,但前提是您事先知道位数。

【讨论】:

  • ...不过,这会以相反的顺序输出数字。
  • 我认为他的输出顺序是相反的
  • 你们俩都是对的。我在最后添加了这个作为警告,谢谢。
  • 感谢您快速而有意义的回答!我什至没有注意到操作被颠倒了。我真傻,哈哈:)
【解决方案2】:

对于c = 123 的情况,您实际上是在这样做:

    str[k] = 12 + '0';
    ascii(3, str, k + 1);

我不确定你打算发生什么,但这可能不是你的意思。

【讨论】:

    【解决方案3】:

    其他答案指出了最重要的错误-您交换了模数和除法;尽管如此,即使进行了更正,产生的字符串也会被反转,因为使用模数你很快就会得到最低有效位,它应该向右,但是你把它放在左边,因为一开始是未知的最终长度字符串。

    您可以反转此字符串,使用对数查找位数或使用替代递归方法:

    void ascii(int c, char str[])
    {
        if(c<0)
        {
            *(str++)='-';
            c=-c;
        }
        *(ascii_helper(c, str))='\0';
    }
    
    char * ascii_helper(int c, char str[])
    {
        if (c > 9)
            str=ascii_helper(c/10, str);
        *str = c%10 + '0';
        return str+1;
    }
    

    这通过推迟数字的实际写入直到它们的位置已知。递归一直持续到找到最高有效数字为止,然后每个调用将下一个字符的位置返回给其调用者,该位置用于正确定位每个数字。请注意,此函数不能像原始函数那样进行尾部优化,因此它的空间效率较低(尽管这几乎无关紧要,因为 ints 通常无论如何不能容纳超过 20 位数字)。

    【讨论】:

      【解决方案4】:
      • 首先你交换了模数和除法,这就是你得到那些意想不到的答案的原因。
      • 此外,这给出了您所期望的相反答案。所以修改数字然后尝试解决它。​​

        void ascii(int c, char str[], int k) {
        /*first let us reverse the string
        because recursive solution will be reverse of our expected solution*/
        int r=0,i;
        for(i=c;i>0;i=i/10)
        r=r*10+i%10;
        
        if (r <= 9) {
            str[k] = r + '0';
        
        }
        else if (r >= 10) {
             ascii(r / 10, str, k+1 );
             str[k] = r%10 + '0';
        }
        return;
        }
        

      【讨论】:

        猜你喜欢
        • 2013-11-17
        • 2016-02-02
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        • 2021-06-11
        • 2012-03-11
        • 2017-05-14
        相关资源
        最近更新 更多