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.

paan
sumber
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))
A. Rex
sumber
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)
jfs
sumber
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));
    }
}
T3db0t
sumber
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,

Rodrigo López
sumber
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

Matt Ellen
sumber
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
Eratosthenes
sumber
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 .

Acumenus
sumber
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;
    }
}'
seperti ini
sumber
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
Aaditya Mishra
sumber
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 ...

SepehrM
sumber
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)
Zach-M
sumber
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) }
}
cmilr
sumber
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)

mohit
sumber
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
mpalanco
sumber
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));
}
Saebekassebil
sumber
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.

Ishak
sumber
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;
}
mehmet riza oz
sumber
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) .

Kai Noack
sumber
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)
Roger Garzon Nieto
sumber
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()))
Alessandro Martin
sumber
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.

yosh kemu
sumber
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);
}
Pengguna
sumber
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++;
    }
}
Behnam Dezfouli
sumber
0
clc;

data = [1 2 3 4 5]

LCM=1;

for i=1:1:length(data)

    LCM = lcm(LCM,data(i))

end 
MD Nashid Anjum
sumber
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;
}
Nikhil
sumber
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; }

vipul
sumber
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'

sumber
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
Vishwajeet Gaur
sumber
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)  
Rodrigo López
sumber
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.)

Hosam Aly
sumber