Am wenigsten gemeinsames Vielfaches für 3 oder mehr Zahlen


152

Wie berechnet man das kleinste gemeinsame Vielfache mehrerer Zahlen?

Bisher konnte ich es nur zwischen zwei Zahlen berechnen. Aber ich habe keine Ahnung, wie ich es erweitern soll, um 3 oder mehr Zahlen zu berechnen.

Bisher habe ich das so gemacht

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

Mit gcd ist die Funktion, den größten gemeinsamen Teiler für die Zahlen zu berechnen. Verwendung eines euklidischen Algorithmus

Aber ich kann nicht herausfinden, wie ich es für 3 oder mehr Zahlen berechnen soll.


74
Bitte kennzeichnen Sie dies nicht als Hausaufgabe. Ich versuche einen Weg zu finden, um mehrere Metallbleche auf eine Platte zu bringen, und muss einen Weg finden, um Metall unterschiedlicher Länge auf dieselbe Platte zu bringen. LCM und GCD sind der beste Weg, dies zu tun. Ich bin ein Programmierer, kein Mathematiker. Darum habe ich gefragt.
Paan

2
Kleine Blätter in ein größeres Blatt einpassen - 2D-Behälterverpackung?
Hochleistungsmarke

3
@ HighPerformanceMark Tetris?
mbomb007

Antworten:


181

Sie können den LCM von mehr als zwei Zahlen berechnen, indem Sie den LCM von zwei Zahlen iterativ berechnen, d. H.

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

10
Ooooh Lehrbuchrekursion :)
Peter Wone

10
Eine rekursive Algorithmusdefinition bedeutet nicht unbedingt eine rekursive Unterroutine. Sie können dies ziemlich einfach in einer Schleife implementieren. Danke für die perfekte Antwort.
Marius

144

In Python (modifizierte 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)

Verwendung:

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

reduce()funktioniert so etwas wie , dass :

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

1
Ich bin nicht mit Python vertraut. Was macht reduct ()?
Paan

17
Wenn eine Funktion f und eine Liste l = [a, b, c, d] gegeben sind, gibt redu (f, l) f (f (f (a, b), c), d) zurück. Es ist die funktionale Implementierung von "lcm kann durch iteratives Berechnen des lcm des aktuellen Werts und des nächsten Elements der Liste berechnet werden."
A. Rex

4
+1 für die Anzeige einer Lösung, die sich an mehr als drei Parameter anpassen kann
OnesimusUnbound

Können Sie die lcm-Funktion wie die lcmm-Funktion verhalten, indem Sie sich selbst reduzieren? Mein erster Gedanke ist, es dazu zu bringen, lcm () zu machen, wenn es zwei Argumente gibt, und redu () zu machen, wenn es mehr gibt.
Endolith

1
@Hairy Komma erstellt ein Tupel in Python. In diesem Fall ist es äquivalent zu:t = a; a = b; b = t % b
jfs

26

Hier ist eine Implementierung im ECMA-Stil:

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
Es fühlt sich schlecht an, dass ich nicht verstehe, was du mit "ECMA-Stil"
meinst

15

Ich würde mit diesem gehen (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);
}

Nur ein paar Klarstellungen, denn auf den ersten Blick ist nicht so klar, was dieser Code tut:

Aggregate ist eine Linq-Erweiterungsmethode, sodass Sie nicht vergessen können, System.Linq zu Ihren Referenzen hinzuzufügen.

Das Aggregat erhält eine Akkumulationsfunktion, sodass wir die Eigenschaft lcm (a, b, c) = lcm (a, lcm (b, c)) über eine IEnumerable verwenden können. Mehr zu Aggregat

Die GCD-Berechnung verwendet den euklidischen Algorithmus .

Die lcm-Berechnung verwendet Abs (a * b) / gcd (a, b), siehe Reduktion um den größten gemeinsamen Teiler .

Hoffe das hilft,


6

Ich habe das gerade in Haskell herausgefunden:

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

Ich habe mir sogar die Zeit genommen, meine eigene gcdFunktion zu schreiben , nur um sie im Prelude zu finden! Viel Lernen für mich heute: D.


1
Sie können foldr1 für die letzte Zeile verwenden: lcm ns = foldr1 lcm' nsoderlcm = foldr1 lcm'
Neil Mayhew

Sie können auch mit dem Ausgabetyp Signaturen, für ein wirklich minimal Ergebnis, wie Integralwird implizitdiv
Neil Mayhew

6

Einige Python-Codes, für die keine Funktion für gcd erforderlich ist:

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)

So sieht es im Terminal aus:

$ python lcm.py 10 15 17
510

6

Hier ist ein Python-Einzeiler (ohne Importe), der den LCM der Ganzzahlen von 1 bis einschließlich 20 zurückgibt:

Python 3.5+ Importe:

from functools import reduce
from math import gcd

Python 2.7-Importe:

from fractions import gcd

Gemeinsame Logik:

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

Beachten Sie, dass sowohl in Python 2 und Python 3 , Betreiber Vorrangregeln diktieren , dass die *und //Operatoren die gleiche Priorität haben, und so sie von links nach rechts an. Als solches x*y // zbedeutet (x*y) // zund nicht x * (y//z). Die beiden führen normalerweise zu unterschiedlichen Ergebnissen. Dies wäre für die Float-Division nicht so wichtig gewesen, aber für die Floor-Division .


3

Hier ist ein C # -Port der Implementierung von 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

Funktion zum Auffinden von lcm einer beliebigen Liste von Zahlen:

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

2

Mit LINQ können Sie schreiben:

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

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

Sollte hinzufügen using System.Linq;und nicht vergessen, die Ausnahmen zu behandeln ...


2

Und die Scala-Version:

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

Hier ist es in 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

Sie können es auch anders machen - Lassen Sie es n Zahlen geben. Nehmen Sie ein Paar aufeinanderfolgender Zahlen und speichern Sie die lcm in einem anderen Array. Wenn Sie dies beim ersten Iterationsprogramm tun, werden n / 2 Iterationen ausgeführt. Nehmen Sie dann das nächste Paar ab 0 wie (0,1), (2,3) usw. auf. Berechnen Sie deren LCM und speichern Sie es in einem anderen Array. Tun Sie dies, bis Sie nur noch ein Array haben. (Es ist nicht möglich, lcm zu finden, wenn n ungerade ist.)


1

In R, können wir die Funktionen mGCD (x) und MLCM (x) aus den Paketnummern , die größten gemeinsamen Teiler und kleinste gemeinsame Vielfache für alle Zahlen in dem Integer - Vektor zusammen x zu berechnen:

    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-Stil

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
Sie haben angerufen, gcd(a, b)aber die gdcFunktion erwartet ein Array, also gcd([a, b])
João Pinto Jerónimo

Dies ist mit Abstand die eleganteste Antwort
Lokua

1

Nur zum Spaß eine Shell-Implementierung (fast jede 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"

versuchen Sie es mit:

$ ./script 2 3 4 5 6

bekommen

60

Die größte Eingabe und das größte Ergebnis sollten kleiner sein als (2^63)-1oder die Shell-Mathematik wird umbrochen.


1

Ich suchte nach gcd und lcm von Array-Elementen und fand eine gute Lösung im folgenden Link.

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

welches folgenden Code enthält. Der Algorithmus für gcd verwendet den euklidischen Algorithmus, der im folgenden Link ausführlich erläutert wird.

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

Hier ist die PHP- Implementierung:

    // 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

Credits gehen an @ T3db0t mit seiner Antwort oben (Code im ECMA-Stil) .


0

GCD benötigt eine kleine Korrektur für negative Zahlen:

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

Wie wäre es damit?

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

Wir haben eine funktionierende Implementierung von Least Common Multiple auf Calculla die für eine beliebige Anzahl von Eingaben funktioniert und auch die Schritte anzeigt.

Was wir tun ist:

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.

Und das war's - du hast dein lcm.


0

LCM ist sowohl assoziativ als auch kommutativ.

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

Hier ist der Beispielcode in 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

Die Methode compLCM nimmt einen Vektor und gibt LCM zurück. Alle Zahlen befinden sich innerhalb des Vektors 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 

Code wird geschätzt, aber wenn Sie Kommentare hinzufügen können, die die Funktionsweise beschreiben, wird er noch mehr geschätzt.
Alex Riley

Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich , die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt! Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, und geben Sie an, welche Einschränkungen und Annahmen gelten.
Toby Speight

0

Wenn Sie nach schnell arbeitendem Code suchen, versuchen Sie Folgendes:

Ich habe eine Funktion geschrieben lcm_n(args, num) , die die lcm aller Zahlen im Array berechnet und zurückgibt args. Der zweite Parameter numist die Anzahl der Zahlen im Array.

Fügen Sie alle diese Zahlen in ein Array ein argsund rufen Sie dann die Funktion wie auflcm_n(args,num);

Diese Funktion gibt die lcm aller dieser Zahlen zurück.

Hier ist die Implementierung der Funktion 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);
    }
}

Diese Funktion benötigt weniger als zwei Funktionen, um zu funktionieren. Fügen Sie sie einfach hinzu.

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

In 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

Das habe ich benutzt -

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

für 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

In Ruby ist es so einfach wie:

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

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

(getestet auf Ruby 2.2.10 und 2.6.3.)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.