문제

누군가가 두 개 이상의 숫자에 대해 가장 큰 일반적인 제수 알고리즘을 찾는 예를 제시 할 수 있습니까?

나는 프로그래밍 언어가 중요하지 않다고 생각합니다.

도움이 되었습니까?

해결책

첫 번째 쌍으로 시작하여 GCD를 얻은 다음 해당 결과의 GCD와 다음 번호를 가져옵니다. 명백한 최적화는 실행중인 GCD가 1에 도달하면 중지 할 수 있다는 것입니다. 다른 최적화가 있는지 확인하기 위해 이것을보고 있습니다. :)

오, 그리고 이것은 운영이 정류/연관성이기 때문에 쉽게 병렬화 될 수 있습니다.

다른 팁

3 숫자의 GCD는 다음과 같이 계산할 수 있습니다 gcd(a, b, c) = gcd(gcd(a, b), c). 유클리드 알고리즘, 확장 유클리드 또는 이진 GCD 알고리즘을 반복적으로 적용하고 답변을 얻을 수 있습니다. 불행히도 GCD를 찾는 다른 (더 똑똑한?) 방법을 모릅니다.

내가 아는 파티에 조금 늦었지만 Sam Harwell의 알고리즘에 대한 설명을 활용하여 간단한 JavaScript 구현 :

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

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

방금 위키 페이지를 업데이트했습니다.

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

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
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top