【问题标题】:Euclid's algorithm欧几里得算法
【发布时间】:2016-07-14 21:08:22
【问题描述】:

在计算gcd(x, y) 的欧几里得算法示例中,x 总是大于y。这个条件重要吗?如果x 小于y 会发生什么?为什么即使x 的输入值小于y,该程序仍然返回正确的结果?

import acm.program.*;
/*
GCD Algorithm - greatest common divisor. "Euclid Algorithm approach"

 */
public class EuclidsAlgorithm extends ConsoleProgram {
    public void run(){
        println("This program is calculating the gratest common divisor (GCD) of two numbers.");
        int x = readInt("Enter 1st number: ");
        int y = readInt("Enter 2nd number: ");
        println("GCD(" + x + ", " + y + ") = " + gcd(x, y) );
    }

    private int gcd(int m, int k){
        int r = m % k;
        while (r != 0){
            m = k;
            k = r;
            r = m % k;
        }
        return k;
    }
}

【问题讨论】:

  • 试试x > yx < y 输入,然后调试。
  • 旁注:在声明中添加staticprivate static int gcd(...)
  • @DmitryBychenko 也许他还应该在方法中添加泛型,以防他想处理 long?.. 为什么要在不必要的地方添加东西?
  • 每个循环都有一个变量移位:m
  • @Coderino Javarino:恕我直言,这取决于。如果您不打算使用 long 等,您可能不想从 primitive 类型迁移到泛型(想象一下,您必须将 gcd 应用于,例如,百万int 对)。

标签: java algorithm


【解决方案1】:

输入的顺序与结果无关。

如果m < k,那么r的初始值就是m;那么m接收k的值,k接收r的值,即m

因此,输入在循环的第一次迭代中被有效地交换,因此m > k

显然,进行第一次迭代以交换输入需要(稍微)更长的时间:如果您能够以输入已经在m > k 顺序中的方式调用该方法,那么您可以节省一些工作。

【讨论】:

  • 这对输出无关紧要,但出于“更软”的原因很重要。示例总是将较大的放在第一位,因为没有人想展示只是交换输入的第一步。如果需要,实际的实现通常会首先交换,因为无论如何它们都必须检查负数和其他东西,这比让循环来做这件事要快,而且代码更容易推断m>=k 在循环中是否不变。跨度>
  • 谢谢@Matt。我在答案中添加了更多内容,但我不会逐字窃取您的评论:)
【解决方案2】:

两个输入的顺序无关紧要,因为:r = m%k

if(m < k)
r = m
if(m == k)
r = 0
if(m > k)
r =  an integer number between 0 and k

而r是一个不断缩小和缩小的数字,直到找到一个可以同时整除两个数字或达到0的数字。

【讨论】:

    【解决方案3】:

    它返回正确的结果,因为当您将较小的数字除以较大的数字时,您得到的模数是较小的数字。

    因此,例如,10%14 将为您提供 10。 因此,按照您的逻辑,如果我们以 10 和 14 为例,将 x 传递为 10 并将 y 传递为 14,我们仍然会得到 2 作为正确答案。 虽然在这段代码中,while 循环将比我们将 x 作为 14y 作为 10 传递多一次强>

    【讨论】:

      【解决方案4】:

      其实没关系 这就是为什么

      GCD(x,y)
        if (y == 0 ) return x
      return GCD(y,x%y)
      

      假设 x = 3,Y = 5

      GCD(3,5) = GCD(5,3%5) = GCD(5,3) = GCD(3,2) .....
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多