3 개 이상의 숫자에 대한 최소 공배수


152

여러 숫자의 최소 공배수를 어떻게 계산합니까?

지금까지 나는 두 숫자 사이에서만 계산할 수있었습니다. 그러나 3 개 이상의 숫자를 계산하기 위해 확장하는 방법을 모릅니다.

지금까지 이것은 내가 한 방법입니다

LCM = num1 * num2 /  gcd ( num1 , num2 )

gcd는 숫자의 최대 공약수를 계산하는 함수입니다. 유클리드 알고리즘 사용

그러나 3 개 이상의 숫자에 대해 계산하는 방법을 알 수 없습니다.


74
이것을 숙제로 태그하지 마십시오. 여러 조각의 금속 시트를 접시에 맞추는 방법을 찾으려고하는데 같은 접시에 다른 길이의 금속을 맞추는 방법을 찾아야합니다. 이를 수행하는 가장 좋은 방법은 LCM과 GCD입니다. 저는 수학자가 아닌 프로그래머입니다. 그게 내가 물었다.
paan

2
작은 시트를 더 큰 시트에 맞추기-2D 빈 포장?
고성능 Mark

3
트윗 담아 가기
mbomb007

답변:


181

두 숫자의 LCM을 반복적으로 계산하여 두 숫자 이상의 LCM을 계산할 수 있습니다.

lcm(a,b,c) = lcm(a,lcm(b,c))

10
Ooooh 교과서 재귀 :)
Peter Wone

10
재귀 알고리즘 정의가 반드시 재귀 서브 루틴을 의미하는 것은 아닙니다. 루프에서 이것을 간단하게 구현할 수 있습니다. 완벽한 답변 주셔서 감사합니다.
Marius

144

파이썬 (modified primes.py )에서 :

def gcd(a, b):
    """Return greatest common divisor using Euclid's Algorithm."""
    while b:      
        a, b = b, a % b
    return a

def lcm(a, b):
    """Return lowest common multiple."""
    return a * b // gcd(a, b)

def lcmm(*args):
    """Return lcm of args."""   
    return reduce(lcm, args)

용법:

>>> lcmm(100, 23, 98)
112700
>>> lcmm(*range(1, 20))
232792560

reduce()그런 식으로 작동 합니다 :

>>> f = lambda a,b: "f(%s,%s)" % (a,b)
>>> print reduce(f, "abcd")
f(f(f(a,b),c),d)

1
파이썬에 익숙하지 않습니다. reduce ()는 무엇을합니까?
paan

17
함수 f와리스트 l = [a, b, c, d]가 주어지면 reduce (f, l)는 f (f (f (a, b), c), d)를 반환합니다. "lcm은 현재 값의 lcm과 목록의 다음 요소를 반복적으로 계산하여 계산할 수 있습니다"의 기능적 구현입니다.
A. Rex

4
3 개 이상의 매개 변수에 적용 할 수있는 솔루션을 보여주는 +1
OnesimusUnbound

lcm 함수가 자체를 줄여서 lcmm 함수처럼 동작하도록 할 수 있습니까? 내 첫 번째 생각은 두 개의 인수가있을 때 lcm ()을 수행하고 더 많은 경우 reduce ()를 수행하는 것입니다.
endolith

1
@Hairy 쉼표는 Python에서 튜플을 만듭니다. 이 경우 다음과 같습니다.t = a; a = b; b = t % b
jfs

26

ECMA 스타일 구현은 다음과 같습니다.

function gcd(a, b){
    // Euclidean algorithm
    var t;
    while (b != 0){
        t = b;
        b = a % b;
        a = t;
    }
    return a;
}

function lcm(a, b){
    return (a * b / gcd(a, b));
}

function lcmm(args){
    // Recursively iterate through pairs of arguments
    // i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))

    if(args.length == 2){
        return lcm(args[0], args[1]);
    } else {
        var arg0 = args[0];
        args.shift();
        return lcm(arg0, lcmm(args));
    }
}

2
그것은 나쁜 느낌이 나는 당신이 "ECMA-스타일"= / 무슨 뜻인지 이해하지 않는
freitass

15

나는 이것 (C #)과 함께 갈 것이다.

static long LCM(long[] numbers)
{
    return numbers.Aggregate(lcm);
}
static long lcm(long a, long b)
{
    return Math.Abs(a * b) / GCD(a, b);
}
static long GCD(long a, long b)
{
    return b == 0 ? a : GCD(b, a % b);
}

언뜻보기 에이 코드가 수행하는 작업이 너무 명확하지 않기 때문에 몇 가지 설명이 필요합니다.

집계는 Linq 확장 방법이므로 System.Linq를 사용하여 참조에 추가하는 것을 잊을 수 없습니다.

집계는 누적 함수를 얻으므로 IEnumerable에서 lcm (a, b, c) = lcm (a, lcm (b, c)) 속성을 사용할 수 있습니다. 집계에 대한 추가 정보

GCD 계산은 유클리드 알고리즘을 사용 합니다 .

lcm 계산은 Abs (a * b) / gcd (a, b)를 사용합니다 . 최대 공약수의 감소를 참조하십시오 .

도움이 되었기를 바랍니다,


6

방금 Haskell에서 이것을 알아 냈습니다.

lcm' :: Integral a => a -> a -> a
lcm' a b = a`div`(gcd a b) * b
lcm :: Integral a => [a] -> a
lcm (n:ns) = foldr lcm' n ns

나는 심지어 gcdPrelude에서만 찾기 위해 내 자신의 함수 를 작성하는 데 시간이 걸렸다 ! 오늘 나를 위해 많은 학습 : D


1
마지막 줄에 foldr1을 사용할 수 있습니다 : lcm ns = foldr1 lcm' ns또는lcm = foldr1 lcm'
Neil Mayhew

당신은 정말 최소한의 결과에 대한 유형 서명과도 분배 등의 수 Integral에 의해 암시div
닐 메이 휴

6

gcd에 대한 함수가 필요하지 않은 일부 Python 코드 :

from sys import argv 

def lcm(x,y):
    tmp=x
    while (tmp%y)!=0:
        tmp+=x
    return tmp

def lcmm(*args):
    return reduce(lcm,args)

args=map(int,argv[1:])
print lcmm(*args)

터미널에서 보이는 모습은 다음과 같습니다.

$ python lcm.py 10 15 17
510

6

다음은 1에서 20까지의 정수의 LCM을 반환하는 Python one-liner (임포트 계산 제외)입니다.

Python 3.5 이상 가져 오기 :

from functools import reduce
from math import gcd

파이썬 2.7 수입품 :

from fractions import gcd

일반적인 논리 :

lcm = reduce(lambda x,y: x*y // gcd(x, y), range(1, 21))

모두 있습니다 파이썬 2파이썬 3 , 연산자 우선 순위 규칙이 있음을 지시 *하고 //연산자가 동일한 우선 순위를 가질, 그들은에서 적용 할 수 있도록 왼쪽에서 오른쪽으로. 따라서 x*y // z의미는 (x*y) // z아닙니다 x * (y//z). 이 둘은 일반적으로 다른 결과를 생성합니다. 이것은 플로트 분할에 대해서는 중요하지 않지만 바닥 분할에 대해서는 중요 합니다.


3

다음은 Virgil Disgr4ce 구현의 C # 포트입니다.

public class MathUtils
{
    /// <summary>
    /// Calculates the least common multiple of 2+ numbers.
    /// </summary>
    /// <remarks>
    /// Uses recursion based on lcm(a,b,c) = lcm(a,lcm(b,c)).
    /// Ported from http://stackoverflow.com/a/2641293/420175.
    /// </remarks>
    public static Int64 LCM(IList<Int64> numbers)
    {
        if (numbers.Count < 2)
            throw new ArgumentException("you must pass two or more numbers");
        return LCM(numbers, 0);
    }

    public static Int64 LCM(params Int64[] numbers)
    {
        return LCM((IList<Int64>)numbers);
    }

    private static Int64 LCM(IList<Int64> numbers, int i)
    {
        // Recursively iterate through pairs of arguments
        // i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))

        if (i + 2 == numbers.Count)
        {
            return LCM(numbers[i], numbers[i+1]);
        }
        else
        {
            return LCM(numbers[i], LCM(numbers, i+1));
        }
    }

    public static Int64 LCM(Int64 a, Int64 b)
    {
        return (a * b / GCD(a, b));
    }

    /// <summary>
    /// Finds the greatest common denominator for 2 numbers.
    /// </summary>
    /// <remarks>
    /// Also from http://stackoverflow.com/a/2641293/420175.
    /// </remarks>
    public static Int64 GCD(Int64 a, Int64 b)
    {
        // Euclidean algorithm
        Int64 t;
        while (b != 0)
        {
            t = b;
            b = a % b;
            a = t;
        }
        return a;
    }
}'


2

LINQ를 사용하면 다음과 같이 작성할 수 있습니다.

static int LCM(int[] numbers)
{
    return numbers.Aggregate(LCM);
}

static int LCM(int a, int b)
{
    return a * b / GCD(a, b);
}

using System.Linq;예외를 추가 하고 처리하는 것을 잊지 않아야합니다 ...


2

스칼라 버전 :

def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
def gcd(nums: Iterable[Int]): Int = nums.reduce(gcd)
def lcm(a: Int, b: Int): Int = if (a == 0 || b == 0) 0 else a * b / gcd(a, b)
def lcm(nums: Iterable[Int]): Int = nums.reduce(lcm)

2

여기 Swift에 있습니다.

// Euclid's algorithm for finding the greatest common divisor
func gcd(_ a: Int, _ b: Int) -> Int {
  let r = a % b
  if r != 0 {
    return gcd(b, r)
  } else {
    return b
  }
}

// Returns the least common multiple of two numbers.
func lcm(_ m: Int, _ n: Int) -> Int {
  return m / gcd(m, n) * n
}

// Returns the least common multiple of multiple numbers.
func lcmm(_ numbers: [Int]) -> Int {
  return numbers.reduce(1) { lcm($0, $1) }
}

1

다른 방법으로 할 수 있습니다-n 개의 숫자가 있어야합니다. 연속 숫자 쌍을 가져 와서 lcm을 다른 배열에 저장하십시오. 첫 번째 반복 프로그램 에서이 작업을 수행하면 n / 2 반복이 수행됩니다. 다음 (0,1), (2,3) 등과 같이 0부터 시작하는 픽업 쌍. LCM을 계산하고 다른 배열에 저장하십시오. 하나의 어레이가 남을 때까지이 작업을 수행하십시오. (n이 홀수이면 lcm을 찾을 수 없습니다)


1

R에서는 패키지 번호 에서 mGCD (x) 및 mLCM (x) 함수를 사용 하여 정수 벡터 x의 모든 숫자에 대해 최대 공약수와 최소 공배수를 함께 계산할 수 있습니다.

    library(numbers)
    mGCD(c(4, 8, 12, 16, 20))
[1] 4
    mLCM(c(8,9,21))
[1] 504
    # Sequences
    mLCM(1:20)
[1] 232792560

1

ES6 스타일

function gcd(...numbers) {
  return numbers.reduce((a, b) => b === 0 ? a : gcd(b, a % b));
}

function lcm(...numbers) {
  return numbers.reduce((a, b) => Math.abs(a * b) / gcd(a, b));
}

1
당신이라고 gcd(a, b)하지만, gdc당신이 전화에 의미 있도록 기능 배열을 기대gcd([a, b])
주앙 핀투 제로니모

이것은 가장 우아한 답변입니다
Lokua

1

재미를 위해서 쉘 (거의 모든 쉘) 구현 :

#!/bin/sh
gcd() {   # Calculate $1 % $2 until $2 becomes zero.
      until [ "$2" -eq 0 ]; do set -- "$2" "$(($1%$2))"; done
      echo "$1"
      }

lcm() {   echo "$(( $1 / $(gcd "$1" "$2") * $2 ))";   }

while [ $# -gt 1 ]; do
    t="$(lcm "$1" "$2")"
    shift 2
    set -- "$t" "$@"
done
echo "$1"

그것을 사용해보십시오 :

$ ./script 2 3 4 5 6

얻을

60

가장 큰 입력과 결과는 (2^63)-1셸 수학 보다 줄어야합니다 .


1

나는 gcd와 lcm의 배열 요소를 찾고 있었고 다음 링크에서 좋은 해결책을 찾았습니다.

https://www.hackerrank.com/challenges/between-two-sets/forum

다음 코드가 포함됩니다. gcd 알고리즘은 아래 링크에서 유클리드 알고리즘을 사용합니다.

https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm

private static int gcd(int a, int b) {
    while (b > 0) {
        int temp = b;
        b = a % b; // % is remainder
        a = temp;
    }
    return a;
}

private static int gcd(int[] input) {
    int result = input[0];
    for (int i = 1; i < input.length; i++) {
        result = gcd(result, input[i]);
    }
    return result;
}

private static int lcm(int a, int b) {
    return a * (b / gcd(a, b));
}

private static int lcm(int[] input) {
    int result = input[0];
    for (int i = 1; i < input.length; i++) {
        result = lcm(result, input[i]);
    }
    return result;
}

1

다음은 PHP 구현입니다.

    // https://stackoverflow.com/q/12412782/1066234
    function math_gcd($a,$b) 
    {
        $a = abs($a); 
        $b = abs($b);
        if($a < $b) 
        {
            list($b,$a) = array($a,$b); 
        }
        if($b == 0) 
        {
            return $a;      
        }
        $r = $a % $b;
        while($r > 0) 
        {
            $a = $b;
            $b = $r;
            $r = $a % $b;
        }
        return $b;
    }

    function math_lcm($a, $b)
    {
        return ($a * $b / math_gcd($a, $b));
    }

    // https://stackoverflow.com/a/2641293/1066234
    function math_lcmm($args)
    {
        // Recursively iterate through pairs of arguments
        // i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))

        if(count($args) == 2)
        {
            return math_lcm($args[0], $args[1]);
        }
        else 
        {
            $arg0 = $args[0];
            array_shift($args);
            return math_lcm($arg0, math_lcmm($args));
        }
    }

    // fraction bonus
    function math_fraction_simplify($num, $den) 
    {
        $g = math_gcd($num, $den);
        return array($num/$g, $den/$g);
    }


    var_dump( math_lcmm( array(4, 7) ) ); // 28
    var_dump( math_lcmm( array(5, 25) ) ); // 25
    var_dump( math_lcmm( array(3, 4, 12, 36) ) ); // 36
    var_dump( math_lcmm( array(3, 4, 7, 12, 36) ) ); // 252

크레딧은 위의 답변 (ECMA 스타일 코드) 으로 @ T3db0t로 이동합니다 .


0

GCD는 음수를 약간 수정해야합니다.

def gcd(x,y):
  while y:
    if y<0:
      x,y=-x,-y
    x,y=y,x % y
    return x

def gcdl(*list):
  return reduce(gcd, *list)

def lcm(x,y):
  return x*y / gcd(x,y)

def lcml(*list):
  return reduce(lcm, *list)

0

이건 어때요?

from operator import mul as MULTIPLY

def factors(n):
    f = {} # a dict is necessary to create 'factor : exponent' pairs 
    divisor = 2
    while n > 1:
        while (divisor <= n):
            if n % divisor == 0:
                n /= divisor
                f[divisor] = f.get(divisor, 0) + 1
            else:
                divisor += 1
    return f


def mcm(numbers):
    #numbers is a list of numbers so not restricted to two items
    high_factors = {}
    for n in numbers:
        fn = factors(n)
        for (key, value) in fn.iteritems():
            if high_factors.get(key, 0) < value: # if fact not in dict or < val
                high_factors[key] = value
    return reduce (MULTIPLY, ((k ** v) for k, v in high_factors.items()))

0

우리는 단계를 표시하는 여러 입력에 대해 작동 하는 Calculla에 최소 공배수 를 구현했습니다 .

우리가하는 일은 :

0: Assume we got inputs[] array, filled with integers. So, for example:
   inputsArray = [6, 15, 25, ...]
   lcm = 1

1: Find minimal prime factor for each input.
   Minimal means for 6 it's 2, for 25 it's 5, for 34 it's 17
   minFactorsArray = []

2: Find lowest from minFactors:
   minFactor = MIN(minFactorsArray)

3: lcm *= minFactor

4: Iterate minFactorsArray and if the factor for given input equals minFactor, then divide the input by it:
  for (inIdx in minFactorsArray)
    if minFactorsArray[inIdx] == minFactor
      inputsArray[inIdx] \= minFactor

5: repeat steps 1-4 until there is nothing to factorize anymore. 
   So, until inputsArray contains only 1-s.

그리고 그게 다야-당신은 당신의 lcm을 얻었다.


0

LCM은 연관적이고 정류 적입니다.

LCM (a, b, c) = LCM (LCM (a, b), c) = LCM (a, LCM (b, c))

다음은 C의 샘플 코드입니다.

int main()
{
  int a[20],i,n,result=1;  // assumption: count can't exceed 20
  printf("Enter number of numbers to calculate LCM(less than 20):");
  scanf("%d",&n);
  printf("Enter %d  numbers to calculate their LCM :",n);
  for(i=0;i<n;i++)
    scanf("%d",&a[i]);
 for(i=0;i<n;i++)
   result=lcm(result,a[i]);
 printf("LCM of given numbers = %d\n",result);
 return 0;
}

int lcm(int a,int b)
{
  int gcd=gcd_two_numbers(a,b);
  return (a*b)/gcd;
}

int gcd_two_numbers(int a,int b)
{
   int temp;
   if(a>b)
   {
     temp=a;
     a=b;
     b=temp;
   }
  if(b%a==0)
    return a;
  else
    return gcd_two_numbers(b%a,a);
}

0

compLCM 메소드는 벡터를 받아서 LCM을 리턴합니다. 모든 숫자는 벡터 in_numbers 내에 있습니다.

int mathOps::compLCM(std::vector<int> &in_numbers)
 {
    int tmpNumbers = in_numbers.size();
    int tmpMax = *max_element(in_numbers.begin(), in_numbers.end());
    bool tmpNotDividable = false;

    while (true)
    {
        for (int i = 0; i < tmpNumbers && tmpNotDividable == false; i++)
        {
            if (tmpMax % in_numbers[i] != 0 )
                tmpNotDividable = true;
        }

        if (tmpNotDividable == false)
            return tmpMax;
        else
            tmpMax++;
    }
}

0
clc;

data = [1 2 3 4 5]

LCM=1;

for i=1:1:length(data)

    LCM = lcm(LCM,data(i))

end 

코드는 높이 평가되지만 작동 방식을 자세히 설명하는 주석을 추가 할 수 있다면 훨씬 더 높이 평가됩니다.
Alex Riley

이 코드 스 니펫은 문제를 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다 . 지금 질문하는 사람뿐만 아니라 앞으로 독자들에게 질문에 대답하고 있음을 기억하십시오! 제발 편집 설명을 추가하고, 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을.
Toby Speight

0

빠른 작업 코드를 찾는 사람은 다음을 시도하십시오.

lcm_n(args, num) 배열의 모든 숫자의 lcm을 계산하고 반환 하는 함수 를 작성했습니다 args. 두 번째 매개 변수 num는 배열의 수입니다.

모든 숫자를 배열에 args넣고 다음과 같이 함수를 호출하십시오.lcm_n(args,num);

이 함수 모든 숫자의 lcm을 반환 합니다.

다음은 함수 구현입니다 lcm_n(args, num).

int lcm_n(int args[], int num) //lcm of more than 2 numbers
{
    int i, temp[num-1];

    if(num==2)
    {
        return lcm(args[0], args[1]);
    }
    else
    {
        for(i=0;i<num-1;i++)
        {
           temp[i] = args[i];   
        }

        temp[num-2] = lcm(args[num-2], args[num-1]);
        return lcm_n(temp,num-1);
    }
}

이 기능이 작동하려면 두 가지 기능이 필요합니다. 따라서 함께 추가하십시오.

int lcm(int a, int b) //lcm of 2 numbers
{
    return (a*b)/gcd(a,b);
}


int gcd(int a, int b) //gcd of 2 numbers
{
    int numerator, denominator, remainder;

    //Euclid's algorithm for computing GCD of two numbers
    if(a > b)
    {
        numerator = a;
        denominator = b;
    }
    else
    {
        numerator = b;
        denominator = a;
    }
    remainder = numerator % denominator;

    while(remainder != 0)
    {
        numerator   = denominator;
        denominator = remainder;
        remainder   = numerator % denominator;
    }

    return denominator;
}

0

int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a%b); } int lcm(int[] a, int n) { int res = 1, i; for (i = 0; i < n; i++) { res = res*a[i]/gcd(res, a[i]); } return res; }


0

파이썬에서 :

def lcm(*args):
    """Calculates lcm of args"""
    biggest = max(args) #find the largest of numbers
    rest = [n for n in args if n != biggest] #the list of the numbers without the largest
    factor = 1 #to multiply with the biggest as long as the result is not divisble by all of the numbers in the rest
    while True:
        #check if biggest is divisble by all in the rest:
        ans = False in [(biggest * factor) % n == 0 for n in rest]
        #if so the clm is found break the loop and return it, otherwise increment factor by 1 and try again
        if not ans:
            break
        factor += 1
    biggest *= factor
    return "lcm of {0} is {1}".format(args, biggest)

>>> lcm(100,23,98)
'lcm of (100, 23, 98) is 112700'
>>> lcm(*range(1, 20))
'lcm of (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) is 232792560'

0

이것이 내가 사용한 것입니다.

def greater(n):

      a=num[0]

      for i in range(0,len(n),1):
       if(a<n[i]):
        a=n[i]
      return a

r=input('enter limit')

num=[]

for x in range (0,r,1):

    a=input('enter number ')
    num.append(a)
a= greater(num)

i=0

while True:

    while (a%num[i]==0):
        i=i+1
        if(i==len(num)):
               break
    if i==len(num):
        print 'L.C.M = ',a
        break
    else:
        a=a+1
        i=0

0

파이썬 3의 경우 :

from functools import reduce

gcd = lambda a,b: a if b==0 else gcd(b, a%b)
def lcm(lst):        
    return reduce(lambda x,y: x*y//gcd(x, y), lst)  

0

루비에서는 다음과 같이 간단합니다.

> [2, 3, 4, 6].reduce(:lcm)
=> 12

> [16, 32, 96].reduce(:gcd)
=> 16

(Ruby 2.2.10 및 2.6.3에서 테스트되었습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.