【问题标题】:How to add 4 or more numbers recursively?如何递归地添加4个或更多数字?
【发布时间】:2020-11-01 15:06:51
【问题描述】:

我正在尝试制作一个超级基本的程序来练习递归。所以我目前正在尝试将4个数字相加,这是我使用的方法:

  public static void recurr(int[] iarr, int target) {
if (iarr.length==1 ) {
  if (iarr[0]==target)
    System.out.println(iarr[0]);
} else {
  for (int ii =0; ii< iarr.length/2;ii++) {
    int p = iarr[ii] + iarr[iarr.length-ii-1];
    int[] piarr=new int[1];
    piarr[0]=p;
    recurr(piarr,target);
  }
}

此方法递归地添加两个数字,但不是 4 个数字及以上。因此,如果我将 1,2,3,4 给 array ,它将添加 1 和 2,然后将添加 3,4 但不会添加 3 和 7,这是相加的结果。如何解决?

【问题讨论】:

  • 一种学习方法是尝试手动写出步骤,然后在代码中实现这些步骤。这不是很递归,如何结束的测试也有点不稳定。尝试解决这些问题,它会帮助您解决整个问题。

标签: java arrays recursion


【解决方案1】:

你的方法到处都是,我不确定它是否可以挽救。

这就是你通常编写递归方法的方式

极端

任何递归方法都需要一种不递归而是返回答案的模式,通常这些模式存在于琐碎的情况下。对于“将此数组中的所有数字相加”的设置,有一个非常明显的平凡模式:空数组中所有数字的总和是多少?当然是 0。

递归操作

任何由于陷入琐碎情况而没有返回的递归方法都需要用“附加”来描述自己。

该操作将执行递归,但参数更接近上述琐碎的退出案例之一(递归方法仍需要在某个点结束,因此您需要朝着那些提前退出的角落前进每个步骤的情况,否则他们永远不会),然后改变递归调用的结果以考虑到您删除的位。

因此,给定一个由 5 个数字组成的数组,递归解决方案将信任递归来产生 5 个数字中的 4 个相加的结果(这是更少的数据,因此更接近 0 长度数组的极端情况) ,然后将添加第 5 个数字并返回它(因为我们删除了第 5 个数字,因此此调用需要以某种方式将其集成到结果中)。

跟踪进度

通常(但不总是),递归方法会传递完整的数据集,而不是每次都切掉一个切片;例如,在每个循环中制作整个数组的完整副本是一项昂贵的操作。相反,您可以传递跟踪信息。在这种情况下,您可以传递数组中的索引。然后,极端情况不再是“空数组”,而是“索引位于数组的末尾”。因为跟踪信息通常“从外部”有点奇怪,所以实际的递归方法是私有的,并且有一些公共方法没有启动进程的跟踪信息。

把它放在一起

您正在查看类似的内容:

public int sum(int[] in) {
    return sum0(in, 0);
}

private int sum0(int[] in, int idx) {
   // First, the extreme case
   if (idx >= in.length) return 0;

   // Then, the recursion
   return in[idx] + sum0(in, idx + 1);
}

通常,递归方法并不是特别有效,但它们看起来很干净。以上内容非常简单干净,与您尝试做的事情形成鲜明对比。

编写递归函数的方法有很多种,作为练习,我建议您尝试通过传入更小的数组来编写它。你不能只制作一个大小为 1 的数组,你必须制作一个大小为 1 的数组,而不是你所拥有的。您可能需要阅读 System.arraycopy,因为您需要使用它。

但是,总是,在编写递归函数时,将其分解为 3 个方面:

  1. 对琐碎的极端情况进行编程(这些不递归)
  2. 对递归调用进行编程(它必须使输入更接近琐碎的极端情况)
  3. 对将切片与递归得到的内容集成的部分进行编程。

对于我上面的代码,是:

  1. 当索引在末尾时。
  2. 将索引上移一位。
  3. 将“my”索引处的数字添加到递归结果中。

【讨论】:

  • 我希望 rzwitserloot 没有给你这样的答案,但请注意,他的递归方法的第一行是如何结束。这在递归程序中通常很重要,知道何时完成并且可以停止递归。
  • 附注。由于两个“sum()”函数具有不同的参数签名,因此无需使它们的名称不同。它们可以被称为“总和”。我会制作接收第二个索引参数 private 的辅助函数,因为您不会直接调用那个。
  • 哦,我的错 - 我称它为 sum0,因为 'x0' 是一种用于命名辅助方法的常见模式,而且它绝对应该是私有的,我将进行编辑。
【解决方案2】:

您可以执行以下操作,例如:

public class MyClass {
    public static int sum(int[] array, int counter) {
        if (array.length -1 == counter) {
            return array[counter];
        } else {
          counter = counter +1;
          return array[counter-1]+sum(array, counter);
        }
    }
    
    public static void main(String args[]) {
     int[] array = new int[4];
     array[0] = 1;
     array[1] = 2;
     array[2] = 3;
     array[3] = 4;
     System.out.println(sum(array,0));
    }
}

输出: 10.

这个想法是迭代直到你到达数组的最后一个值,在这种情况下你返回那个元素,以便它可以添加到前一个元素等等。方法的第二个参数作为一个停止器,所以你在最后一个元素处停止迭代。还有其他实现相同行为的方法,但这是其中之一,我认为它很容易掌握和重现。

【讨论】:

    【解决方案3】:
    public static int sumWithRecursion(int... arr) {
        return sumWithRecursion(arr, 0);
    }
    
    private static int sumWithRecursion(int[] arr, int i) {
        return arr.length == i ? 0 : arr[i] + sumWithRecursion(arr, i + 1);
    }
    

    输出:

    System.out.println(sumWithRecursion(1, 2, 3, 4));   // 10
    

    【讨论】:

      猜你喜欢
      • 2019-10-21
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多