递归如何在此代码中找到GCD?

时间:2019-07-25 17:14:24

标签: java recursion

我碰到了这段代码,用于从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方法在此代码中如何工作?

3 个答案:

答案 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);

       }
    }