【问题标题】:C: Recursive function for inverting an intC:用于反转 int 的递归函数
【发布时间】:2012-07-06 00:20:52
【问题描述】:

我昨天考试时遇到了这个问题。我无法解决它,所以你可以想象结果......

创建一个递归函数:int invertint(int num),它将接收一个整数并将其返回但反转,例如:321 将返回为 123

这是我写的:

int invertint( int num ) {
  int rest = num % 10;
  int div = num / 10;
  if( div == 0 ) {
     return( rest );
  }
  return( rest * 10 + invert( div ) )
}

适用于 2 位数字,但不适用于 3 位或更多位。因为 321 在最后阶段会返回 1 * 10 + 23

非常感谢!

PS:有没有办法以更快的方式理解这类递归问题,还是靠自己的想象?

【问题讨论】:

  • 您是否考虑过将其转换为 char* 并使用 char* 调用递归函数?这可能会让事情变得更容易,但我不知道你是否被允许这样做
  • 1230 的结果是什么,3210321
  • @JoSo 我认为整数中不能有前导 0 ......所以我猜它会是:1230: 321
  • 如果您正在查看有关如何解决此类问题的提示,我的建议是 1) 尝试坚持使用 if(is_base_case){ basecase } else { recursive_case } 结构。它通过练习变得自然,并且 2)学习如何将尾递归转换为 while 循环,反之亦然。很多问题都属于这一类

标签: c recursion integer


【解决方案1】:

这是最简单的方法。

int sum=0;
int reverse(int n)
{
    if(n>0)
    {
        sum=(sum*10)+(n%10);
        reverse(n/10);
    }
    return sum;
}

【讨论】:

  • 为什么要使用全局变量?
【解决方案2】:

作为替代方案,这可以在没有递归的情况下完成。

    int invertint(int num)
    {
        int res = 0;
        while (num != 0)
        {                
            res = res * 10 + (num % 10);
            num /= 10;
        }
        return res;
    }

但是由于递归是分配,给定 int(int) 签名,最简单的方法是使用 pow(log10)) 变体(前提是您可以包含 math.h ?)

    int invertint(int num)
    {
        if (num == 0) return 0;
        return invertint(num / 10)  +  (int)pow(10, (int)log10(num)) * (num % 10);
    }

【讨论】:

    【解决方案3】:
    int reverse(int no,int rev)
    {
    if(no!=0)
    return reverse(no/10,rev*10+no%10);
    else
    return rev;
    }
    

    将此方法称为reverse(numberToReverse,0)

    【讨论】:

    • 你的第二个函数并没有真正起作用,你甚至没有使用递归调用的结果。
    • 不,它不会工作。您甚至没有从函数返回值。 -1 表示你显然没有测试它时争论。
    • @interjay 我已删除该功能。测试完我会贴出来的。
    • 好的,-1 已删除。我认为没有一个简单的方法可以在不添加额外参数或计算位数的情况下回答问题。
    【解决方案4】:

    如果你反其道而行之,就不需要计数器了。

    int invertint(int num)
    {
        if (0 == num || 0 == num % 10) {
            return num / 10;
        }
        int digits = floor(log10(num)) + 1;
        int modulus = pow(10, digits - 1);
        return invertint(num % modulus) * 10 + num / modulus;
    }
    

    请注意,这并不像我最初想象的那么简单 - 我必须使用数学。

    【讨论】:

    • 这与 Rafael Baptista 的回答相同,同样错误。
    • @interjay:实际上,你是对的。让我再考虑一下。
    • 是的,它现在应该可以工作了,+1。我不认为考试题很好,因为它要求你要么使用浮点数来计算数字,要么使用循环(当使用递归时这很愚蠢)。
    • @interjay:同意。可悲的是,我认为这很常见,出于某种原因,大多数递归的“教学”示例都不是很好地使用递归。
    【解决方案5】:
    int invertint( int num ) {
      int i ;
    
      for(i=10;num/i;i*=10);
      i/=10;
      if(i == 1) return num;
      return( (num % 10) * i + invertint( num / 10 ) );
    }
    

    【讨论】:

    • 完美运行,谢谢。如果不令人不安,你能解释一下你是怎么想的吗?谢谢!
    • @Jorge:想法是反过来递归——而不是先处理最右边的数字,而是处理最左边的数字。这就是循环在这里所做的,log10/pow 组合在我的回答中所做的。剩下的就很自然了。
    • @Jorge - i:10^floor(log10(num)),cha0site 解释。
    【解决方案6】:

    您的错误是在最后一个语句中您将rest 乘以10。为什么只有10?您需要将rest 数字移动与数字剩余部分中剩余的数字一样多的数字。你只移动了 1。难怪它只适用于 2 位数字。

    最后一部分应该按照

    int tail = invert( div );
    int deg = /* number of digits in `tail` */;
    return rest * (int) pow(10, deg) + div;
    

    【讨论】:

    • +1。这就是答案,我也想到了。但是,不应该是(尾部的位数 - 1)。例如:321有3位,所以最后一次执行时应该是rest * pow(10, 2)。
    • @Jay: tail 在这种情况下实际上是数字的 剩余 部分(已经通过递归调用提供)。 IE。如果原始号码是321,那么rest1,而tail23。所以,deg 将是 2,正如它应该的那样。但是,如果tail 在反转后以前导零结尾,我已经看到此解决方案存在问题。应在递归调用之前计算位数。 BLUEPIXY 在公认的解决方案中正确地做到了。
    【解决方案7】:

    问题在于return(rest * 10 + invert(div))。你不能自己做乘法。该因素取决于函数递归的次数,因此您必须提供进位作为函数的第二个参数(进位初始化为 0)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2013-07-27
      • 2013-03-20
      • 1970-01-01
      • 2011-03-26
      • 2021-04-16
      相关资源
      最近更新 更多