简体   繁体   English

给定数字N,如何调用递归调用N次?

[英]how to call a recursion call N number of times, given the number N?

I have an array of numbers: S= {4,5} and I want to check if this group creates the sum = 13 .我有一个数字数组: S= {4,5} ,我想检查这个组是否创建sum = 13

In this case, yes: 4 + 4 + 5 = 13在这种情况下,是: 4 + 4 + 5 = 13

Another example: s={4,5} , sum = 6 -> no另一个例子: s={4,5} , sum = 6 -> no

I wrote a recursive function to solve this:我写了一个递归函数来解决这个问题:

public static boolean isSumOf(int [] s,int n)
    {
        if(n == 0)
            return true;
        if(n < 0)
            return false;

        return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
    }

But this function works only for 2 numbers in the array.但此函数仅适用于数组中的 2 个数字。 I need to write a recursive function that will deal with N numbers, like {4,9,3} or {3,2,1,7} etc.我需要编写一个递归函数来处理 N 个数字,例如{4,9,3}{3,2,1,7}等。

I'm not sure how can I do this?我不确定我该怎么做? How can I call a recursion N times, according to the length of the array?如何根据数组的长度调用递归 N 次? Or maybe I should change my algorithm completely?或者我应该完全改变我的算法? Also - I'm not allowed to use loops.另外 - 我不允许使用循环。

return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);

You can generalize this with a loop like this:你可以用这样的循环来概括这一点:

for (int i = 0; i < s.length; ++i) {
  if (isSumOf(s,n-s[i])) return true;
}
return false;

But, since you can't use loops, you can write the equivalent loop as another recursive method:但是,由于您不能使用循环,您可以将等效循环编写为另一种递归方法:

boolean withoutLoop(int [] s,int n, int i) {
  if (i >= s.length) return false;
  return isSumOf(s,n-s[i]) || recurse(s, n, i+1);
}

and then call it like so from your isSumOf method:然后从你的isSumOf方法中像这样调用它:

public static boolean isSumOf(int [] s,int n)
{
    if(n == 0)
        return true;
    if(n < 0)
        return false;

    return withoutLoop(s, n, 0);  // Change here.
}

Or, if you want to write it more concisely:或者,如果你想写得更简洁:

return (n == 0) || (n < 0 && withoutLoop(s, n, 0));

Break the problem down:分解问题:

  1. Sum the numbers对数字求和
  2. Is the sum equal to 13?总和等于 13 吗?

Then think of a way to express summing an array as recursive task;然后想办法来表达总结数组作为递归任务; eg Sum of elements 1 to N is element 1 + Sum of elements 2 to N.例如,元素 1 到 N 的总和是元素 1 + 元素 2 到 N 的总和。

Finally, turn that idea / expression into code.最后,将这个想法/表达转化为代码。

For any recursion problem, use the template:对于任何递归问题,请使用模板:

ResultType recursiveMethod(params) {
     if( /* this is the simplest case */ ) {
         return answer for the simplest case
     } else {
         partialResult = solve part of the problem
         resultForRest = recursiveMethod(rest of problem)
     }
}

Particularly for list processing, this becomes:特别是对于列表处理,这变为:

if(list is empty) {
    return solution for an empty list
} else {
    r = call self recursively for tail of list
    return solution for head of list combined with r
}

(Where "head" is the first item, and "tail" is the rest. Tail may be empty.) (其中“head”是第一项,“tail”是其余项。tail 可能为空。)

For your problem, the simplest case is an empty array:对于您的问题,最简单的情况是空数组:

 if(s.length == 0) {
      return n == 0;
 }

For the else , the "part of the problem" is s[0] and the "rest of the problem" is s[1] onwards.对于else ,“问题的一部分”是s[0]而“问题的其余部分”是s[1]

 ... 
 } else {
     int head = s[0];
     int[] tail = Arrays.copyOfRange(s,1,s.length-1);
     return isSumOf(tail, n - head);
 }

The code would be cleaner (and probably more efficient) if you used a List instead of an array directly, because you could then use List.subList() instead of copyOfRange() .如果您直接使用List而不是数组,代码会更清晰(并且可能更高效),因为您可以使用List.subList()而不是copyOfRange()

You could also pass the whole array each time, along with an extra parameter indicating how much of the array has already been accounted for.您还可以每次都传递整个数组,以及一个额外的参数,该参数指示已经考虑了多少数组。

This should work:这应该有效:

public static boolean isSumOf(int [] s,int n)
    {
        if(n == 0)
            return true;
        if(n < 0)
            return false;

        for (int x: s) {
            if (isSumOf(s, n-x)) {
                return true;
            }
        }
        return false;
    }

UPDATE:更新:

Oh!哦! no loop, only recursion, you will need an extra argument:没有循环,只有递归,你需要一个额外的参数:

public static boolean isSumOf(int [] s,int n)
    {
        if(n == 0)
            return true;
        if(n < 0)
            return false;

        return isSum2(s, n, 0);
    }

public static boolean isSum2(int [] s,int n,int i)
    {
        if (i >= s.length)
            return false;

        return isSumOf(s,n-s[i]) || isSum2(s,n,i+1);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM