【问题标题】:from recursion to iteration从递归到迭代
【发布时间】:2013-12-31 04:11:34
【问题描述】:

我有递归函数:

public static int fRek(int n) {         
    if (n <= 0)
       return 1;            
    else if (n == 1) 
       return 2;       
    else
       return 3 * fRek(n-2)-3;  
}

问题:如何在迭代中编写它?循环? 我有这个:

public static int fIter(int a) {
    int b = 1 ;
        if (a <= 0) return 1;           
        else if (a == 1) return 2;  
        for (int i = 1; i <= a; i = i+2) {            
              b = b * 3;            
              b = b - 3;        
        }        
        return b;    
    }
}

但它只适用于偶数:a = 4,6,8,... 对于奇数,它不能正常工作,我不知道为什么

【问题讨论】:

  • 自己试试吧。如果您发现任何问题,请回来并描述它们。

标签: java function recursion iteration


【解决方案1】:

对于偶数,您的第二个算法将不起作用,因为在第一段代码中,如果 n == 1 函数返回 2

else if (n == 1) 
   return 2;     

在你的第二个算法中,如果输入参数a 是奇数,for 循环最终会将其减少为1 而不是0,因此使用b=1 进行计算是不正确的。 a为奇数时应使用b=2a为偶数时应使用b=1

此外,您应该使用 i=1 的 for 循环,而 a 是奇数,i=2a 是偶数。

【讨论】:

    【解决方案2】:

    是的循环,虽然在这种情况下不是那么容易,因为函数不是尾递归的。

    让我们首先将其转换为尾递归函数。为此,我们传递一个参数,说明临时结果必须通过最终函数x =&gt; 3*x-3 的频率:

    public static int fRek1(int n, int count) {
       if (n <= 0) return finalf(1, count);
       else if (n == 1) return finalf(2, count);
       else return fRek(n-2, count+1);
    }
    public static int fRek(int n) { return fRek1(n, 0); }
    public static int finalf(int n, int count) {
        while (count > 0) {
           n = 3*n-3;
           count--;
        }
        return n;
    }
    

    现在您可能会看到如何将上面的 fRek1 转换为 while 循环:只需将递归替换为一个块,其中变量 n 和 count 获取它们的新值并将方法体包含在 while (true) 中。

    【讨论】:

      【解决方案3】:

      您的第二个问题仍在尝试以递归方式解决此问题。您需要将逻辑分解为 While 语句。这是一个开始:

      int tmp = n
      while (tmp > 1) {
      
      Insert main logic here
      
      }
      //Base Cases
      if (tmp == 1)
          n += 3 
      
      if (tmp <= 0)
          n += 0 //This does nothing but listing for illustration
      
      return n;
      

      【讨论】:

        【解决方案4】:

        它适用于偶数的原因是因为您在函数开始时对相应的停止条件进行了硬编码。

        看看你的递归函数。如果是偶数,会递归调用直到n == 0;也就是说,直到我们到达这里:

        if (n <= 0)
           return 1; 
        

        从那里,我们自下而上计算最终结果。

        return 3 * 1 -3;  //that's 0 
        return 3 * 0 -3;  //that's -3
        return 3 * -3 -3; //that's -12
        return 3 * 3 -3;  //that's -39
        //...and so on
        

        如果数字是奇数,我们从 2 开始,因为这条线:

        else if (n == 1) 
           return 2;  
        

        从那里,我们自下而上计算最终结果。

        return 3 * 2 -3;  //that's 3 
        return 3 * 3 -3;  //that's 6
        return 3 * 6 -3;  //that's 15
        return 3 * 15 -3;  //that's 42
        //... and so on    
        

        你的迭代函数是这样开始的。

        int b = 1 ;
        

        也就是说,您施加的条件仅应在数字为偶数的情况下存在。相反,您应该测试数字是偶数还是奇数。

        if (a % 2 == 0) 
            b = 1;           
        else 
            b = 2;  
        for (int i = b; i <= a; i = i+2) {    
            //...
        }
        

        【讨论】:

          猜你喜欢
          • 2012-01-23
          • 2016-11-10
          • 2021-03-17
          相关资源
          最近更新 更多