Kelipatan umum terkecil untuk 3 atau lebih angka


152

Bagaimana Anda menghitung kelipatan angka yang paling umum?

Sejauh ini saya hanya bisa menghitungnya di antara dua angka. Tetapi tidak tahu bagaimana mengembangkannya untuk menghitung 3 angka atau lebih.

Sejauh ini begitulah cara saya melakukannya

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

Dengan gcd adalah fungsi untuk menghitung pembagi umum terbesar untuk angka-angka. Menggunakan algoritma euclidean

Tapi saya tidak tahu bagaimana cara menghitungnya untuk 3 angka atau lebih.


74
tolong jangan beri tag ini sebagai pekerjaan rumah. Saya mencoba menemukan cara untuk memasukkan beberapa lembar lembaran logam ke piring dan perlu menemukan cara untuk memasang logam dengan panjang berbeda di piring yang sama. LCM dan GCD adalah cara terbaik untuk melakukan ini. Saya seorang programmer bukan orang matematika. Itulah mengapa saya bertanya.
paan

2
Menyesuaikan lembaran kecil ke dalam lembaran yang lebih besar - Pengemasan bin 2D?
High Performance Mark

3
@HighPerformanceMark Tetris?
mbomb007

Jawaban:


181

Anda dapat menghitung LCM lebih dari dua angka dengan secara iteratif menghitung LCM dari dua angka, yaitu

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

10
Rekursi buku teks Ooooh :)
Peter Wone

10
definisi algoritma rekursif tidak selalu berarti subrutin rekursif. Anda dapat menerapkan ini dalam satu lingkaran cukup sederhana. Terima kasih atas jawaban yang sempurna.
Marius

144

Dengan Python (modifikasi 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)

Pemakaian:

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

reduce()bekerja seperti itu :

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

1
Saya tidak terbiasa dengan python, apa yang mengurangi () lakukan?
paan

17
Diberikan fungsi f dan daftar l = [a, b, c, d], mengurangi (f, l) mengembalikan f (f (f (a, b), c), d). Ini implementasi fungsional "lcm dapat dihitung dengan menghitung iteratif lcm dari nilai saat ini dan elemen selanjutnya dari daftar."
A. Rex

4
+1 untuk menunjukkan solusi yang dapat beradaptasi dengan lebih dari tiga parameter
OnesimusUnbound

dapatkah Anda membuat fungsi lcm berperilaku seperti fungsi lcmm dengan mengurangi sendiri? Pikiran pertama saya adalah membuatnya melakukan lcm () ketika ada 2 argumen, dan melakukan pengurangan () ketika ada lebih banyak.
endolith

1
@Hairy comma menciptakan tuple dengan Python. Dalam hal ini, ini setara dengan:t = a; a = b; b = t % b
jfs

26

Berikut ini adalah implementasi gaya 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
Rasanya tidak enak bahwa saya tidak mengerti apa yang Anda maksud dengan "ECMA-style" = /
freitas

15

Saya akan memilih yang ini (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);
}

Hanya beberapa klarifikasi, karena pada pandangan pertama tidak begitu jelas apa yang dilakukan kode ini:

Agregat adalah metode Ekstensi Linq, jadi Anda tidak bisa lupa menambahkan menggunakan System.Linq ke referensi Anda.

Agregat mendapatkan fungsi terakumulasi sehingga kita dapat menggunakan properti lcm (a, b, c) = lcm (a, lcm (b, c)) melalui IEnumerable. Lebih lanjut tentang Agregat

Perhitungan GCD memanfaatkan algoritma Euclidean .

Perhitungan lcm menggunakan Abs (a * b) / gcd (a, b), lihat Pengurangan oleh pembagi umum terbesar .

Semoga ini membantu,


6

Saya baru saja menemukan ini di 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

Saya bahkan meluangkan waktu untuk menulis gcdfungsi saya sendiri , hanya untuk menemukannya di Prelude! Banyak pembelajaran untuk saya hari ini: D


1
Anda dapat menggunakan foldr1 untuk baris terakhir: lcm ns = foldr1 lcm' nsataulcm = foldr1 lcm'
Neil Mayhew

Anda juga dapat membuang jenis tanda tangan, untuk hasil yang benar-benar minimal, seperti Integralyang dinyatakan olehdiv
Neil Mayhew

6

Beberapa kode Python yang tidak memerlukan fungsi untuk 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)

Begini tampilannya di terminal:

$ python lcm.py 10 15 17
510

6

Berikut ini adalah satu-baris Python (tidak termasuk impor) untuk mengembalikan LCM dari bilangan bulat dari 1 hingga 20 inklusif:

Python 3.5+ impor:

from functools import reduce
from math import gcd

Impor Python 2.7:

from fractions import gcd

Logika umum:

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

Perhatikan bahwa di kedua Python 2 dan Python 3 , aturan operator didahulukan menentukan bahwa *dan //operator memiliki prioritas yang sama, dan sehingga mereka berlaku dari kiri ke kanan. Dengan demikian, x*y // zberarti (x*y) // zdan tidak x * (y//z). Keduanya biasanya menghasilkan hasil yang berbeda. Ini tidak akan jadi masalah bagi divisi float tetapi itu bagi divisi lantai .


3

Berikut ini adalah porta C # dari implementasi 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

Berfungsi untuk menemukan lcm dari daftar angka apa pun:

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

2

Menggunakan LINQ Anda bisa menulis:

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

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

Harus menambahkan using System.Linq;dan jangan lupa untuk menangani pengecualian ...


2

Dan versi 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

Ini dia di 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

Anda bisa melakukannya dengan cara lain - Biarkan ada n angka. Ambil sepasang angka berurutan dan simpan lcm di array lain. Melakukan ini pada program iterasi pertama tidak n / 2 iterasi. Kemudian pick up pasangan mulai dari 0 seperti (0,1), (2,3) dan seterusnya. Hitung LCM mereka dan simpan di array lain. Lakukan ini sampai Anda tersisa dengan satu larik. (tidak mungkin menemukan lcm jika n ganjil)


1

Dalam R, kita dapat menggunakan fungsi mGCD (x) dan mLCM (x) dari nomor paket , untuk menghitung pembagi umum terbesar dan kelipatan paling umum untuk semua angka dalam vektor integer x bersama-sama:

    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

Gaya 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
Anda menelepon gcd(a, b)tetapi gdcfungsi tersebut mengharapkan array sehingga Anda bermaksud memanggilgcd([a, b])
João Pinto Jerónimo

ini adalah jawaban yang paling elegan sejauh ini
Lokua

1

Hanya untuk bersenang-senang, implementasi shell (hampir semua shell):

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

coba dengan:

$ ./script 2 3 4 5 6

mendapatkan

60

Input dan hasil terbesar harus kurang dari (2^63)-1atau shell shell akan membungkus.


1

saya sedang mencari elemen array gcd dan lcm dan menemukan solusi yang baik di link berikut.

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

yang mencakup kode berikut. Algoritma untuk gcd menggunakan Algoritma Euclidean yang dijelaskan dengan baik di tautan di bawah ini.

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

Berikut ini adalah implementasi 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

Kredit pergi ke @ T3db0t dengan jawabannya di atas (kode gaya ECMA) .


0

GCD perlu sedikit koreksi untuk angka negatif:

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

Bagaimana dengan ini?

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

Kami memiliki implementasi kerja Multiple Least Common on Calculla yang berfungsi untuk sejumlah input yang juga menampilkan langkah-langkahnya.

Apa yang kami lakukan adalah:

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.

Dan itu saja - Anda punya cmm Anda.


0

LCM bersifat asosiatif dan komutatif.

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

di sini adalah kode sampel dalam 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

Metode compLCM mengambil vektor dan mengembalikan LCM. Semua angka dalam vektor in_number.

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 

Kode dihargai, tetapi jika Anda dapat menambahkan komentar yang merinci cara kerjanya, itu lebih dihargai.
Alex Riley

Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang! Harap edit jawaban Anda untuk menambahkan penjelasan, dan berikan indikasi batasan dan asumsi apa yang berlaku.
Toby Speight

0

Bagi siapa pun yang mencari kode kerja cepat, coba ini:

Saya menulis sebuah fungsi lcm_n(args, num) yang menghitung dan mengembalikan lcm dari semua angka dalam array args. Parameter kedua numadalah jumlah angka dalam array.

Masukkan semua angka-angka itu dalam sebuah array argsdan kemudian panggil fungsi sepertilcm_n(args,num);

Fungsi ini mengembalikan lcm dari semua angka-angka itu.

Berikut ini adalah implementasi dari fungsinya 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);
    }
}

Fungsi ini perlu di bawah dua fungsi untuk bekerja. Jadi, tambahkan saja bersama dengannya.

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

Dengan python:

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

Inilah yang saya gunakan -

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

untuk python 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

Di Ruby, sesederhana itu:

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

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

(diuji pada Ruby 2.2.10 dan 2.6.3.)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.