对于我在uni的离散结构类,我需要编写一个解决下面公式的方法:
s [0] = 1
s [n-1] = s [n-2] + n所有n> = 2
不幸的是,之前我没有实现过很多递归方法,所以我真的不知道自己在做什么。对我来说,事情就像他们通常那样“点击”。
我会以任何可能的方式感谢你的帮助,但我宁愿完全理解这一点,而不仅仅是复制其他人的工作。
如果n = 8 ...
,该方法应该完成的基本示例1 + 2 = 3 ,
3 + 3 = 6 ,
6 + 4 = 10 ,
10 + 5 = 15 ,
15 + 6 = 21 ,
21 + 7 = 28 ,
28 + 8 = 36,我们的答案。
我已经写了一个方法来解决这个 NON - 递归(如下所示),所以我理解它背后的数学。
public static int sequenceNonRecursive(int n){
int[] s = new int[n];
s[0] = 1;
if(n >= 2){
for(int i = 1; i < n; i++){
s[i] = s[i-1] + i + 1;
}
}
return s[n-1];
}
编辑:我解决了。谢谢大家的帮助!请看下面的答案。
答案 0 :(得分:1)
复发的定义有点奇怪。我会改写它:
S 0 = 1
S i = S i-1 + i + 1 - ∀i&gt; 0
该例程可以简化为不使用数组:
public static int sequenceNonRecursive (int n) {
int S_0 = 1; // 0th term is 1
int S_i = S_0; // S_i starts at S_0
for(int i = 1; i <= n; i++) {
int S_i_minus_1 = S_i; // use previous result to calculate next
S_i = S_i_minus_1 + i + 1; // next is previous added with index plus 1
}
return S_i;
}
任何循环都可以转换为等效的递归例程。诀窍是局部变量变成递归例程的函数参数,循环控制变成if
。如果条件为false,则函数返回结果。否则,该函数将计算视为循环体,然后使用递归进行迭代。
举例说明,给定功能:
public static int someFunction (int n) {
int result = DEFAULT_RESULT;
for (int i = 0; i < n; ++i) {
result = UPDATE_RESULT(i, n, result);
}
return result;
}
然后,可以更改此函数的主体以调用递归函数:
public static int someFunction (int n) {
return someFunctionWithRecursion(n, 0, DEFAULT_RESULT);
}
注意局部变量的初始值是如何转换为递归例程的参数的。因此,递归例程本身可能如下所示:
public static int someFunctionWithRecursion (int n, int i, int result) {
if (! (i < n)) {
return result;
}
result = UPDATE_RESULT(i, n, result);
return someFunctionWithRecursion(n, i+1, result);
}
请注意,在递归调用中,result
已更新,控制变量i
已递增,就像原始for()
循环版本中的迭代一样代码。
顺便说一下:你正在处理的事件实际上是一个封闭的形式:
S n =(½)(n + 1)(n + 2)
答案 1 :(得分:0)
将代码构造成这样的东西(仅提供提示,让您找出问题的其余部分):
public static int sequenceRecursive(int n){
if( n == 0 )
//return something....
else
//return something else, which recursively relies on previous values of sequenceRecursive()
}
答案 2 :(得分:0)
递归就像将原始问题分解为子问题并尝试解决它们。首先,您需要弄清楚基本情况(在您的情况下是n=0
)。现在,您可以通过将其分解为基本案例来了解如何处理n > 0
的案例。创建n
然后n-1
然后n-2
等序列,直到达到基本案例是递归解决此问题的关键。
答案 3 :(得分:0)
让我们先在你的第二个等式中为所有n
添加1 :(如果我们增加它们,我们需要减小范围,看它是正确的应该是微不足道的)
s[0] = 1
s[n] = s[n-1] + (n+1) for all n >= 1
我们为什么要这样做?
简而言之,函数定义为sequence(int n)
,而不是sequence(int n-1)
。
此处s[i]
只对应于使用输入参数i
调用您的函数。
代码的基本思路:
public static int sequence(int n){
if (/* base case */)
// return value for base case
else
// return other case, includes calling sequence(x) for some x
}
希望能给你足够的工作。
答案 4 :(得分:0)
实际上更容易。想象一下,你的方法适用于所有n,除非n为零(基本情况),否则你使用
sequenceRecursive(n-1)
获取前一个数字的值,并希望它能够正常工作。 (它会)
在引擎盖下,它将递归到基本案例并在调用返回时构建值。
答案 5 :(得分:0)
我明白了,伙计们。感谢所有你的帮助!我无法相信这是多么愚蠢。我一想到这一点,就给自己一个强有力的面孔。我现在很确定我理解递归了。
public static int sequenceRecursive(int n){
if( n == 0 )
return 0;
else
return n + sequenceRecursive(n-1);
}