Euclidean greatest common divisor for more than two numbers

前端 未结 6 1363
谎友^
谎友^ 2020-12-16 14:48

Can someone give an example for finding greatest common divisor algorithm for more than two numbers?

I believe programming language doesn\'t matter.

6条回答
  •  无人及你
    2020-12-16 15:26

    I just updated a Wiki page on this.

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

    This takes an arbitrary number of terms. use GCD(5, 2, 30, 25, 90, 12);

    template 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;
    };
    

提交回复
热议问题