Bội số chung cho 3 số trở lên


152

Làm thế nào để bạn tính bội số chung nhỏ nhất của nhiều số?

Cho đến nay tôi chỉ có thể tính được nó giữa hai số. Nhưng không có ý tưởng làm thế nào để mở rộng nó để tính 3 số trở lên.

Cho đến nay đây là cách tôi đã làm nó

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

Với gcd là hàm để tính ước số chung lớn nhất cho các số. Sử dụng thuật toán euclide

Nhưng tôi không thể tìm ra cách tính nó cho 3 số trở lên.


74
xin vui lòng không gắn thẻ này là bài tập về nhà. Tôi đang cố gắng tìm cách lắp nhiều miếng kim loại vào một tấm và cần tìm cách lắp kim loại có chiều dài khác nhau trên cùng một tấm. LCM và GCD là cách tốt nhất để làm điều này. Tôi là một lập trình viên không phải là một người toán học. Đó là lý do tại sao tôi hỏi.
paan

2
Lắp tấm nhỏ vào tấm lớn hơn - Đóng gói thùng 2D?
Đánh dấu hiệu suất cao

3
@HighPerformanceMark Tetris?
mbomb007

Câu trả lời:


181

Bạn có thể tính LCM của hơn hai số bằng cách tính toán lặp lại LCM của hai số, tức là

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

10
Đệ quy sách giáo khoa Ooooh :)
Peter Wone

10
một định nghĩa thuật toán đệ quy không nhất thiết có nghĩa là một chương trình con đệ quy. Bạn có thể thực hiện điều này trong một vòng lặp khá đơn giản. Cảm ơn câu trả lời hoàn hảo.
Marius

144

Trong Python (đã sửa đổi 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)

Sử dụng:

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

reduce()hoạt động như thế :

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

1
Tôi không quen thuộc với python, làm gì () làm gì?
paan

17
Cho hàm số f và danh sách l = [a, b, c, d], giảm (f, l) trả về f (f (f (a, b), c), d). Đó là việc thực hiện chức năng của "lcm có thể được tính bằng cách lặp lại tính toán lcm của giá trị hiện tại và phần tử tiếp theo của danh sách."
A. Rex

4
+1 để hiển thị một giải pháp có thể thích ứng với hơn ba tham số
OnesimusUnbound

bạn có thể làm cho hàm lcm hoạt động giống như hàm lcmm bằng cách tự giảm không? Suy nghĩ đầu tiên của tôi là làm cho nó thực hiện lcm () khi có 2 đối số và thực hiện giảm () khi có nhiều hơn.
endolith

1
Dấu phẩy @Herry tạo một tuple trong Python. Trong trường hợp này, nó tương đương với:t = a; a = b; b = t % b
jfs

26

Đây là cách triển khai theo kiểu 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
Tôi cảm thấy tồi tệ khi tôi không hiểu ý của bạn về "phong cách ECMA" = /
freitass

15

Tôi sẽ đi với cái này (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);
}

Chỉ cần làm rõ một chút, bởi vì thoạt nhìn, nó không rõ ràng những gì mã này đang làm:

Tổng hợp là một phương thức mở rộng Linq, vì vậy bạn không thể quên sử dụng System.Linq vào tài liệu tham khảo của mình.

Tập hợp có một hàm tích lũy để chúng ta có thể sử dụng thuộc tính lcm (a, b, c) = lcm (a, lcm (b, c)) trên một IEnumerable. Thêm về Uẩn

Tính toán GCD sử dụng thuật toán Euclide .

Tính toán lcm sử dụng abs (a * b) / gcd (a, b), tham khảo Giảm theo ước số chung lớn nhất .

Hi vọng điêu nay co ich,


6

Tôi chỉ tìm ra điều này trong 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

Tôi thậm chí đã dành thời gian để viết gcdchức năng của riêng mình , chỉ để tìm thấy nó trong Prelude! Rất nhiều học tập cho tôi ngày hôm nay: D


1
Bạn có thể sử dụng Foldr1 cho dòng cuối cùng: lcm ns = foldr1 lcm' nshoặclcm = foldr1 lcm'
Neil Mayhew

Bạn cũng có thể phân phối với các chữ ký loại, cho một kết quả thực sự tối thiểu, như Integralđược ngụ ý bởidiv
Neil Mayhew

6

Một số mã Python không yêu cầu chức năng cho gcd:

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)

Đây là những gì nó trông giống như trong thiết bị đầu cuối:

$ python lcm.py 10 15 17
510

6

Dưới đây là một lớp lót Python (không tính nhập khẩu) để trả về LCM của các số nguyên từ 1 đến 20 bao gồm:

Nhập khẩu Python 3.5+:

from functools import reduce
from math import gcd

Nhập khẩu Python 2.7:

from fractions import gcd

Logic thông thường:

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

Lưu ý rằng trong cả Python 2Python 3 , các quy tắc ưu tiên toán tử chỉ ra rằng các toán tử *//toán tử có cùng mức ưu tiên và do đó chúng áp dụng từ trái sang phải. Như vậy, x*y // zcó nghĩa là (x*y) // zvà không x * (y//z). Hai thường tạo ra kết quả khác nhau. Điều này sẽ không quan trọng bằng phân chia phao nhưng đối với phân chia sàn .


3

Đây là một cổng C # của việc cấy ghép Virgil Disgr4ce:

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

3

Chức năng tìm lcm của bất kỳ danh sách các số:

 def function(l):
     s = 1
     for i in l:
        s = lcm(i, s)
     return s

2

Sử dụng LINQ bạn có thể viết:

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

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

Nên thêm using System.Linq;và đừng quên xử lý các ngoại lệ ...


2

Và phiên bản Scala:

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

Đây là 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

bạn có thể làm theo cách khác - Để có n số. Lấy một cặp số liên tiếp và lưu lcm của nó vào một mảng khác. Thực hiện điều này ở chương trình lặp đầu tiên thực hiện n / 2 lần lặp. Sau đó, cặp tiếp theo bắt đầu từ 0 như (0,1), (2,3), v.v. Tính toán LCM của chúng và lưu trữ trong một mảng khác. Làm điều này cho đến khi bạn còn lại với một mảng. (không thể tìm thấy lcm nếu n là số lẻ)


1

Trong R, chúng ta có thể sử dụng các hàm mGCD (x) và mLCM (x) từ các số gói , để tính ước số chung lớn nhất và bội số chung nhỏ nhất cho tất cả các số trong vectơ số nguyên x với nhau:

    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

Phong cách 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
Bạn đã gọi gcd(a, b)nhưng gdchàm mong đợi một mảng nên bạn muốn gọigcd([a, b])
João Pinto Jerónimo

đây là câu trả lời tao nhã nhất từ ​​trước đến nay
Lokua

1

Chỉ để cho vui, một vỏ (hầu như bất kỳ vỏ) nào:

#!/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"

thử nó với:

$ ./script 2 3 4 5 6

để có được

60

Đầu vào và kết quả lớn nhất phải nhỏ hơn (2^63)-1hoặc toán vỏ sẽ bao bọc.


1

tôi đã tìm kiếm gcd và lcm của các phần tử mảng và tìm thấy một giải pháp tốt trong liên kết sau đây.

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

trong đó bao gồm mã sau đây. Thuật toán cho gcd sử dụng Thuật toán Euclide được giải thích tốt trong liên kết bên dưới.

https://www.khanacademy.org/computing/computer-science/cryptography/modarithatures/a/the-euclidean-alerskym

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

Đây là cách triển khai 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

Tín dụng đi tới @ T3db0t với câu trả lời của anh ta ở trên (mã kiểu ECMA) .


0

GCD cần một chút hiệu chỉnh cho các số âm:

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

Còn cái này thì sao?

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

Chúng tôi đã thực hiện triển khai Least Common bội trên Calculla , hoạt động cho bất kỳ số lượng đầu vào nào cũng hiển thị các bước.

Những gì chúng tôi làm là:

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.

Và đó là nó - bạn đã có lcm của bạn.


0

LCM là cả kết hợp và giao hoán.

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

đây là mã mẫu trong 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

Phương thức compLCM lấy một vectơ và trả về LCM. Tất cả các số nằm trong vector 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 

Mã được đánh giá cao, nhưng nếu bạn có thể thêm ý kiến ​​chi tiết về cách thức hoạt động thì nó được đánh giá cao hơn nữa.
Alex Riley

Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ là người hỏi bây giờ! Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những hạn chế và giả định được áp dụng.
Toby Speight

0

Đối với bất cứ ai đang tìm kiếm mã làm việc nhanh chóng, hãy thử điều này:

Tôi đã viết một chức năng lcm_n(args, num) tính toán và trả về lcm của tất cả các số trong mảng args. Tham số thứ hainum là số lượng các số trong mảng.

Đặt tất cả những số đó vào một mảng args và sau đó gọi hàm nhưlcm_n(args,num);

Chức năng này trả về lcm của tất cả các số đó.

Dưới đây là việc thực hiện chức năng 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);
    }
}

Chức năng này cần dưới hai chức năng để làm việc. Vì vậy, chỉ cần thêm chúng cùng với nó.

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

Trong trăn:

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

Đây là những gì tôi đã sử dụng -

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

cho trăn 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

Trong Ruby, nó đơn giản như:

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

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

(đã thử nghiệm trên Ruby 2.2.10 và 2.6.3.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.