我碰到了这段代码,用于从here
中查找数字数组的GCD//Function to return gcd of a and b
static int gcd(int a, int b) {
if (a == 0) {
return b;
}
return gcd(b % a, a);
}
// Function to find gcd of array of
// numbers
static int findGCD(int arr[], int n) {
int result = arr[0];
for (int i = 1; i < n; i++) {
result = gcd(arr[i], result);
}
return result;
}
方法gcd
使用递归调用gcd(b % a, a)
。那么这个递归调用是如何工作的呢?我知道递归工作原理的基础,但是我对这段代码中的gcd
方法如何使用递归感到有些困惑。谁能简单地向我解释一下gcd
方法在此代码中如何工作?
答案 0 :(得分:1)
让我们取两个数字24和60,您将函数称为gcd(24, 60)
,然后函数堆栈执行如下,
gcd(24,60) => 60%24 = 12
gcd(24,12) => 12%24 = 12 (Switch happens)
gcd(12,24) => 24%12 = 0
gcd(0 ,12) => terminates
因此在第二步进行的切换非常重要,因为调用基本上会交换两个数字,就像您以迭代方式进行操作一样,将其视为简写方式。
我可以使用与第一个调用相同的示例,即60和24,然后gcd(60,24)
将执行为
gcd(60,24) => 24%60 = 24 (Switch happens)
gcd(24,60) => 60%24 = 12 and this follows the same pattern as the above
此处发生切换是因为这些函数将b%a
发送给下一个函数a
,并将a
发送给该函数b
。
答案 1 :(得分:1)
给出两个数字12和8:
gcd(12,8)计算b%a = 12%8 = 4,然后调用gcd(4,8)。它尚未返回,因为最后一个调用尚未完成。
gcd(4,8)计算b%a = 8%4 = 0,然后调用gcd(0,4)。该呼叫还没有返回,因为该呼叫处于活动状态。
gcd(0,4)分支到第一个if
语句中,并返回4。
这定义了gcd(4,8)的返回值,因此挂起的调用也返回4。
这再次定义了gcd(12,8)的返回值,因此最终结果仍为4。
其背后的数学也很有趣。
我认为主要问题是:为什么我们可以将gcd(12,8)减小为gcd(4,8)?
我们假设存在任何结果g都可以除以12,而没有余数;而除以8,就没有余数。
我们可以将12分成g * n(4 * 3)和8分成g * m(4 * 2)。
接下来,我们可以说12-8 = g n-g m = g *(n-m)(4 *(3-2)= 4)。因此,g不仅将12和8除以除数,还除以12-8(4)。
您甚至可以使用更低的数字:12-8-8 = g ng mg m = g (nmm)(4 *(3-2-2 )=-4)。依此类推。
对于更大的数字也是如此:12 + 8 = g n + g m = g *(n + m)(4 *(3 + 2)= 20)。您可以通过添加8次来重复该操作。
此方法所能获得的最小正数是12%8,因为您可以多次从12中减去8,直到剩下余数。
答案 2 :(得分:1)
为帮助理解递归方法,通常将print
语句放在关键位置很有用,这样您就可以跟踪正在发生的事情。
通过使用专门选择的prime factors
调用方法,很容易确保特定的gcd
。
在下面的示例中,3
是唯一的公因数,因此它将是两个数字的gcd。
public class RecursiveGCD {
public static void main(String[] args) {
System.out.println("GCD = " + gcd(2 * 3 * 4 * 4 * 5, 3 * 7 * 11));
}
public static int gcd(int a, int b) {
System.out.println("\nFinding gcd of a=" + a + " and b=" + b);
if (a == 0) {
System.out.println("a == 0 so returning b (gcd) = " + b);
return b;
}
System.out.println(
"Remainder non-zero, calling with gcd(b % a, a) = gcd(" + (b % a)
+ ", " + a + ").");
return gcd(b % a, a);
}
}