代码之家  ›  专栏  ›  技术社区  ›  Bogdan Gusiev

两个以上数的欧氏最大公约数

  •  14
  • Bogdan Gusiev  · 技术社区  · 17 年前

    有人能举一个例子,找出两个以上数字的最大公因数算法吗?

    我相信编程语言无关紧要。

    6 回复  |  直到 8 年前
        1
  •  30
  •   Sam Harwell    17 年前

    从第一对开始,得到他们的gcd,然后得到结果的gcd和下一个数字。最明显的优化是,如果运行的gcd达到1,就可以停止。我在看这个,看看是否还有其他的优化。:)

    哦,这可以很容易地并行化,因为操作是交换/结合的。

        2
  •  7
  •   Saurav Sahu    9 年前

    3个数字的gcd可以计算为 gcd(a, b, c) = gcd(gcd(a, b), c) . 您可以迭代应用欧几里得算法、扩展欧几里得算法或二进制GCD算法,并得到您的答案。我不知道还有什么(更聪明的?)不幸的是,找到GCD的方法。

        3
  •  3
  •   gwpmad    10 年前

    我知道派对有点晚了,但是一个简单的javascript实现,利用SamHarwell对算法的描述:

    function euclideanAlgorithm(a, b) {
        if(b === 0) {
            return a;
        }
        const remainder = a % b;
        return euclideanAlgorithm(b, remainder)
    }
    
    function gcdMultipleNumbers(...args) { //ES6 used here, change as appropriate
      const gcd = args.reduce((memo, next) => {
          return euclideanAlgorithm(memo, next)}
      );
    
      return gcd;
    }
    
    gcdMultipleNumbers(48,16,24,96) //8
    
        4
  •  0
  •   Nathan Tuggy TonyLuigiC    11 年前

    在Java中(不是最优的):

    public static int GCD(int[] a){
        int j = 0;
    
        boolean b=true;
        for (int i = 1; i < a.length; i++) {
            if(a[i]!=a[i-1]){
                b=false;
                break;
            }
        }
        if(b)return a[0];
        j=LeastNonZero(a);
        System.out.println(j);
        for (int i = 0; i < a.length; i++) {
            if(a[i]!=j)a[i]=a[i]-j;
        }
        System.out.println(Arrays.toString(a));
        return GCD(a);
    }
    
    public static int LeastNonZero(int[] a){
        int b = 0;
        for (int i : a) {
            if(i!=0){
                if(b==0||i<b)b=i;
            }
        }
        return b;
    }
    
        5
  •  0
  •   Paul Baxter    10 年前

    我刚刚更新了一个维基网页。

    [ https://en.wikipedia.org/wiki/Binary_GCD_algorithm#C.2B.2B_template_class]

    这需要任意数量的术语。 使用GCD(5、2、30、25、90、12);

    template<typename AType> AType GCD(int nargs, ...)
    {
        va_list arglist;
        va_start(arglist, nargs);
    
        AType *terms = new AType[nargs];
    
        // put values into an array
        for (int i = 0; i < nargs; i++) 
        {
            terms[i] = va_arg(arglist, AType);
            if (terms[i] < 0)
            {
                va_end(arglist);
                return (AType)0;
            }
        }
        va_end(arglist);
    
        int shift = 0;
        int numEven = 0;
        int numOdd = 0;
        int smallindex = -1;
    
        do
        {
            numEven = 0;
            numOdd = 0;
            smallindex = -1;
    
            // count number of even and odd
            for (int i = 0; i < nargs; i++)
            {
                if (terms[i] == 0)
                    continue;
    
                if (terms[i] & 1)
                    numOdd++;
                else
                    numEven++;
    
                if ((smallindex < 0) || terms[i] < terms[smallindex])
                {
                    smallindex = i;
                }
            }
    
            // check for exit
            if (numEven + numOdd == 1)
                continue;
    
            // If everything in S is even, divide everything in S by 2, and then multiply the final answer by 2 at the end.
            if (numOdd == 0)
            {
                shift++;
                for (int i = 0; i < nargs; i++)
                {
                    if (terms[i] == 0)
                        continue;
    
                    terms[i] >>= 1;
                }
            }
    
            // If some numbers in S  are even and some are odd, divide all the even numbers by 2.
            if (numEven > 0 && numOdd > 0)
            {
                for (int i = 0; i < nargs; i++)
                {
                    if (terms[i] == 0)
                        continue;
    
                    if ((terms[i] & 1)  == 0) 
                        terms[i] >>= 1;
                }
            }
    
            //If every number in S is odd, then choose an arbitrary element of S and call it k.
            //Replace every other element, say n, with | n−k | / 2.
            if (numEven == 0)
            {
                for (int i = 0; i < nargs; i++)
                {
                    if (i == smallindex || terms[i] == 0)
                        continue;
    
                    terms[i] = abs(terms[i] - terms[smallindex]) >> 1;
                }
            }
    
        } while (numEven + numOdd > 1);
    
        // only one remaining element multiply the final answer by 2s at the end.
        for (int i = 0; i < nargs; i++)
        {
            if (terms[i] == 0)
                continue;
    
            return terms[i] << shift;
        }
        return 0;
    };
    
        6
  •  0
  •   RockOnGom    8 年前

    对于golang,使用余数

    func GetGCD(a, b int) int {
        for b != 0 {
            a, b = b, a%b
        }
        return a
    }
    func GetGCDFromList(numbers []int) int {
        var gdc = numbers[0]
        for i := 1; i < len(numbers); i++ {
            number := numbers[i]
            gdc  = GetGCD(gdc, number)
        }
        return gdc
    }