Pergunta

Qual seria a maneira mais fácil de calcular o maior divisor comum e múltiplo menos comum em um conjunto de números? Quais funções de matemática podem ser usadas para encontrar essas informações?

Foi útil?

Solução

Eu usei Algoritmo de Euclides encontrar o maior divisor comum de dois números; Pode ser iterado obter o GCD de um conjunto maior de números.

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

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

O múltiplo menos comum é um pouco mais complicado, mas provavelmente a melhor abordagem é redução pelo GCD, que pode ser igualmente iterado:

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

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

Outras dicas

Há um Algoritmo de Euclides para GCD,

public int GCF(int a, int b) {
    if (b == 0) return a;
    else return (GCF (b, a % b));
}

A propósito, a e b deve ser maior ou igual 0, e LCM = |ab| / GCF(a, b)

Não há construção em função para isso. Você pode encontrar o GCD de dois números usando Algoritmo de Euclides.

Para um conjunto de número

GCD(a_1,a_2,a_3,...,a_n) = GCD( GCD(a_1, a_2), a_3, a_4,..., a_n )

Aplique -o recursivamente.

O mesmo para LCM:

LCM(a,b) = a * b / GCD(a,b)
LCM(a_1,a_2,a_3,...,a_n) = LCM( LCM(a_1, a_2), a_3, a_4,..., a_n )

Se você pode usar o Java 8 (e realmente deseja), pode usar expressões Lambda para resolver isso funcionalmente:

private static int gcd(int x, int y) {
    return (y == 0) ? x : gcd(y, x % y);
}

public static int gcd(int... numbers) {
    return Arrays.stream(numbers).reduce(0, (x, y) -> gcd(x, y));
}

public static int lcm(int... numbers) {
    return Arrays.stream(numbers).reduce(1, (x, y) -> x * (y / gcd(x, y)));
}

Eu me orientei em Resposta de Jeffrey Hantin, mas

  • calculou o GCD funcionalmente
  • Usei o varargs-syntax para uma API mais fácil (eu não tinha certeza se a sobrecarga funcionaria corretamente, mas funcionaria na minha máquina)
  • transformou o GCD do numbers-Anchar a sintaxe funcional, que é mais compacta e IMO mais fácil de ler (pelo menos se você estiver acostumado a programação funcional)

Essa abordagem é provavelmente um pouco mais lenta devido a chamadas de função adicionais, mas isso provavelmente não importará para o maior número de casos de uso.

int gcf(int a, int b)
{
    while (a != b) // while the two numbers are not equal...
    { 
        // ...subtract the smaller one from the larger one

        if (a > b) a -= b; // if a is larger than b, subtract b from a
        else b -= a; // if b is larger than a, subtract a from b
    }

    return a; // or return b, a will be equal to b either way
}

int lcm(int a, int b)
{
    // the lcm is simply (a * b) divided by the gcf of the two

    return (a * b) / gcf(a, b);
}
int lcmcal(int i,int y)
{
    int n,x,s=1,t=1;
    for(n=1;;n++)
    {
        s=i*n;
        for(x=1;t<s;x++)
        {
            t=y*x;
        }
        if(s==t)
            break;
    }
    return(s);
}

Com o Java 8, existem maneiras mais elegantes e funcionais de resolver isso.

LCM:

private static int lcm(int numberOne, int numberTwo) {
    final int bigger = Math.max(numberOne, numberTwo);
    final int smaller = Math.min(numberOne, numberTwo);

    return IntStream.rangeClosed(1,smaller)
                    .filter(factor -> (factor * bigger) % smaller == 0)
                    .map(factor -> Math.abs(factor * bigger))
                    .findFirst()
                    .getAsInt();
}

GCD:

private static int gcd(int numberOne, int numberTwo) {
    return (numberTwo == 0) ? numberOne : gcd(numberTwo, numberOne % numberTwo);
}

Obviamente, se um argumento for 0, ambos os métodos não funcionarão.

por gcd você cad faz como abaixo:

    String[] ss = new Scanner(System.in).nextLine().split("\\s+");
    BigInteger bi,bi2 = null;
    bi2 = new BigInteger(ss[1]);
    for(int i = 0 ; i<ss.length-1 ; i+=2 )
    {
        bi = new BigInteger(ss[i]);
        bi2 = bi.gcd(bi2);
    }
    System.out.println(bi2.toString());

Basicamente, para encontrar GCD e LCM em um conjunto de números que você pode usar abaixo da fórmula,

LCM(a, b) X HCF(a, b) = a * b

Enquanto isso, em Java, você pode usar o algoritmo de Euclides para encontrar GCD e LCM, assim

public static int GCF(int a, int b)
{
    if (b == 0)
    {
       return a;
    }
    else
    {
       return (GCF(b, a % b));
    }
}

Você pode se referir isto Recurso para encontrar exemplos no algoritmo de Euclides.

importar java.util.scanner; classe pública lcmhcf {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    Scanner scan = new Scanner(System.in);
    int n1,n2,x,y,lcm,hcf;
    System.out.println("Enter any 2 numbers....");
    n1=scan.nextInt();
    n2=scan.nextInt();
    x=n1;
    y=n2;

    do{
       if(n1>n2){
         n1=n1-n2;
       }
       else{
         n2=n2-n1;
       }
     } while(n1!=n2);
     hcf=n1;
     lcm=x*y/hcf;
     System.out.println("HCF IS = "+hcf);
     System.out.println("LCM IS = "+lcm);

     }
 }
//## Heading ##By Rajeev Lochan Sen
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n0 = input.nextInt(); // number of intended input.
        int [] MyList = new int [n0];

        for (int i = 0; i < n0; i++)
            MyList[i] = input.nextInt();
            //input values stored in an array
        int i = 0;
        int count = 0;
            int gcd = 1; // Initial gcd is 1
            int k = 2; // Possible gcd
            while (k <= MyList[i] && k <= MyList[i]) {
                if (MyList[i] % k == 0 && MyList[i] % k == 0)
                    gcd = k; // Update gcd
                k++;
                count++; //checking array for gcd
            }
           // int i = 0;
            MyList [i] = gcd;
            for (int e: MyList) {
                System.out.println(e);

            }

            }

        }
import java.util.*;
public class lcm {
    public static void main(String args[])
    {
        int lcmresult=1;
        System.out.println("Enter the number1: ");
        Scanner s=new Scanner(System.in);
        int a=s.nextInt();
        System.out.println("Enter the number2: ");
        int b=s.nextInt();
        int max=a>b?a:b;
        for(int i=2;i<=max;i++)
        {
            while(a%i==0||b%i==0)
            {
                lcmresult=lcmresult*i;
                if(a%i==0)
                    a=a/i;
                if(b%i==0)
                    b=b/i;
                if(a==1&&b==1)
                    break;
            }
        }
    System.out.println("lcm: "+lcmresult);
}
}
int lcm = 1;
int y = 0;
boolean flag = false;
for(int i=2;i<=n;i++){
            if(lcm%i!=0){
                for(int j=i-1;j>1;j--){
                    if(i%j==0){
                        flag =true;
                        y = j;
                        break;
                    }
                }
                if(flag){
                    lcm = lcm*i/y;
                }
                else{
                    lcm = lcm*i;
                }
            }
            flag = false;
        }

Aqui, primeiro para o Loop é para obter todos os números a partir de '2'. Então, se a declaração verificar se o número (i) divide o LCM, se o fizer, pule que não. E se não for, o próximo para o loop é para encontrar um não. que pode dividir o número (i) se isso acontecer, não precisamos disso não. Nós só queremos seu fator extra. Então, aqui se a bandeira for verdadeira, isso significa que já teve alguns fatores de não. 'Eu' em LCM. Portanto, dividimos esses fatores e multiplicamos o fator extra para o LCM. Se o número não for divisível por nenhum de seus não. Então, quando simplesmente o multiplique para o LCM.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top