Ir ao conteúdo
  • Cadastre-se

C++ Exercício de MDC. Linguagem C / C++.


Ir à solução Resolvido por Midori,

Posts recomendados

Pessoal , boa noite. como eu faço um codigo em linguagem C / C++ para calcular o MDC de 3 (três) números? Sei fazer o calculo para dois números e irei deixar o código para usar como referência.

Grato desde já.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
using namespace std;
  
  int mdc(int a, int b){ // Forma iterativa
    int resto;

    while(b != 0){
        resto = a % b;
        a = b;
        b = resto;

    }
    return a;

}
  
  int main()
{
    setlocale(LC_ALL,"Portuguese");


    int num1, num2, num3;


        cout << "Digite dois números para calcular o MDC: ";
        cin >> num1 >> num2;

        mdc(num1,num2);
            cout << "O MDC é: " << mdc(num1,num2);





    return 0;

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Midori Muito Obrigado Midori! Por favor,  você pode explicar a lógica por trás da chamada 2x nessa sua solução? O codigo ficou assim:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
using namespace std;
  
  int mdc(int a, int b){ // Forma iterativa
    int resto;

    while(b != 0){
        resto = a % b;
        a = b;
        b = resto;

    }
    return a;

}
 
int main()
{
    setlocale(LC_ALL,"Portuguese");


    int num1, num2, num3;


        cout << "Digite dois números para calcular o MDC: ";
        cin >> num1 >> num2 >> num3;

        mdc(num1,num2);
            cout << "O MDC é: " << mdc(mdc(num1,num2),num3);





    return 0;

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

bom,o compilador vai ver a 1 função e vai ver qual os dois números que vão ser os do calculo do mdc. então aí no primeiro número tem a função do mdc correto? então o valor do pimeiro número é o valor dessa função. porque essa fução também é um int , mas com parametros( os números que vão ser referencia para a função). então é a mesma coisa que por uma variavel int nesse lugar. Mas qual é o valor dessa função? É o valor de retorno. e qual é o valor de retorno? o mdc dos números dentro dos parenteses. Então basicamente quando o compilador ver o primeiro parametro, ele vê uma variável e olha o valor dessa variavel, que é o mdc dos dois primeiros números, depois disso olha o depois dessa 2 função e ve um numero. Então calcula o mdc dos dois primeiros com o terceiro. 
Resumo:

a 1 função olha os valores que deve calcular o mdc

o 1 valor é o retorno de outro mdc

pega o resultado desse 2 mdc

e a 1 função faz o mdc desse resultado com o outro número que recebeu, o num3.

É meio difícil de explicar, espero que entenda 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Daniel Bittencourt Entendi mais ou menos kkkkkk. Dps vou buscar saber mais sobre. Pra 4 números, o ideal é fazer um "vetor[4]", correto? Ainda fiquei meio confuso sobre a estrutura do codigo. Caso possa replicar meu codigo comentando, acho q fica mais legível. Perdoe meu amadorismo, estou começando no ramo.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solução

@Ricardo_Nascimento  Como mdc é uma função, ela vai executar um conjunto de comandos e retornar um valor. A sua função está definida com dois parâmetros inteiros (int a e int b), então quando chamar a função você terá que passar dois números inteiros como argumento.

 

Se quiser calcular p.ex o mdc de 32 e 48, é só passar esse valores para a função:

x = mdc(32, 48);

 

Com essa chamada o valor de x será mdc de 32 e 48.

 

Mas se você quiser calcular p.ex o mdc de 32, 48 e 120 e sua função só tem 2 parâmetros, primeiro você terá que calcular o mdc de dois números e depois o mdc desse resultado com o terceiro, p.ex,


x = mdc(32, 48);
y = mdc(x, 120);

 

É o mesmo resultado de y = mdc(mdc(32, 48), 120);

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Ricardo_Nascimento não, um vetor é apenas uma forma mais fácil de se referir a algumas variáveis ou para declarar várias juntas. exemplo:

int numero[40],valor=0;
for(int conta=0;conta<40;conta++){
numero[conta]=valor;
valor+=30;                                                                    
}                                  

você economiza um tempo do que fazer isso:

int numero0=0,numero1 = 30,numero2 = 60,numero3 = 90,numero4 = 120,numero5 = 150.....numero40=1200;

imagina escrever 40 declarações '-'

no primeiro exemplo,a parte do int facilita na declaração e o for em se referir mais fácil com o "indíce'' da variável. esse ''indíce'' facilita muito em muitos casos.

no caso de de um mdc de quatro números:

mdc(mdc(num1,num2),mdc(num3,num4));

cinco numeros:

mdc(mdc(mdc(num1,num2),num3),mdc(num4,num5));

seis:

mdc(mdc(mdc(num1,num2),num3),mdc(mdc(num4,num5),num6));

obvio que no caso de muitos números é muito mais fácil fazer como o midori falou:

//4 números
int x = mdc(mdc(num1,num2),num3);
int res = mdc(x,num4);
//ou então assim, fácil de entender, mas maior:
int x = mdc(num1,num2);
int y = mdc(x,num3);
int res = mdc(y,num4);
//5 números, como eu faria:
int x = mdc(num1,num2);
int y = mdc(x,mdc(num3,num4));
int res = mdc(y,num5);

dá para saber como prosseguir se precisar correto?

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

22 horas atrás, Ricardo_Nascimento disse:

você pode explicar a lógica por trás da chamada 2x

 

  • O MDC é associativo. Essa é a lógica. O MDC é C, comum ao grupo, D, divisor, divide todos do grupo, e M, maior valor nessas condições, para um grupo de argumentos.

Exemplo

Calculando o MDC(a,b,c) :

  • Se x = MDC(a,b)
  • MDC(x,c) é o MDC(a,b,c)

E de modo similar

  • Se y = MDC(a,c)
  • MDC(y,b) é o MDC(a,b,c)

Tendo isso como uma função em C++ então se pode omitir a variável intermediária e escrever direto

  • MDC(a,b,c) = MDC( MDC(a,b),c)
  • ou mesmo MDC(a,b,c,d) = MDC( MDC( MDC(a,b),c), d) 

Só vai ficando difícil de ler, mas se pode estender a um número qualquer de argumentos.

  • E como o MDC é um produto ele também é comutativo, de modo que o MDC(a,b) = MDC(b,a) e isso vale também para qualquer permutação. Assim:
    • MDC( a,b,c,d,...) = MDC( b,d,a,c...)

 

"Forma iterativa"
 

int mdc(int a, int b)
{ // Forma iterativa
    int resto;

    while(b != 0){
        resto = a % b;
        a = b;
        b = resto;

    }
    return a;
}

 

Essa "forma iterativa" é o método de Euclides como ensinado no ensino fundamental.

 

A outra forma ensinada no ensino fundamentalMDC.png.e5e3bc583034464b9e2e65abc9942ed0.png para operar com vários números ao mesmo tempo também é, claro, interativa.

Não consigo imaginar uma forma não interativa de fazer isso.

 

Um programa poderia ter essa saída como no ensino fundamental, e seria "bonitinho" de ver como solução, replicando o que se faz com o papel e caneta. 

 

Por exemplo, algo assim para (90, 210,100)

    

MDC( 90 210 100 )

  90   210   100  |    2
  45   105    50  |    2
  45   105    25  |    3
  15    35    25  |    3
   5    35    25  |    5
   1     7     5  |    5
   1     7     1  |    7
   1     1     1

MDC = 2 x 5

 90 = 2     x 3 x 3 x 5
210 = 2     x     3 x 5     x 7
100 = 2 x 2 x         5 x 5
      *               * 
      2        x      5 = 10

 

 

22 horas atrás, Ricardo_Nascimento disse:

Pra 4 números, o ideal é fazer um "vetor[4]", correto? Ainda fiquei meio confuso sobre a estrutura do codigo

 

Citação

Para qualquer caso é melhor usar um vetor. Assim não precisa pensar em nada mais, já que funciona para qualquer número de argumentos.

 

Como o problema já foi resolvido vou mostrar uma maneira mais simples (como eu vejo, claro).

 

A estrutura mais simples provavelmente seria algo assim
 

struct MDC
{
    vector<int> valor;
    int         mdc;
    int         Euclides(int, int);

    MDC(const vector<int>&);
};

 

Porque tem a função Euclides() dentro, e o vetor e o próprio MDC.

 

Como usar?

 

Para o exemplo MDC(90, 210, 180) talvez não possa ser mais simples:
 

    MDC um_grupo( { 90, 210, 100 });
    cout << "MDC = " << um_grupo.mdc << endl;

 

Mas pode ser mais simples se puder escrever cout << um_grupo redefinindo o operador << para MDC, mas fica ruim de ler aqui. Se achar importante escreva e posto um exemplo
 

E vai mostrar "MDC = 10"
 

toninho@DSK-2009:~/projects/dsp$ g++ -o p1 -Wall -std=c++2a -O3 mdc.cpp
toninho@DSK-2009:~/projects/dsp$ ./p1
MDC = 10
toninho@DSK-2009:~/projects/dsp$ 

 

E como calcular o MDC assim, em C++ e com essa struct?
 

MDC::MDC(const vector<int>& valor) : mdc(valor[0])
{
    for (int i = 1; i < (int)valor.size(); i += 1) mdc = Euclides(mdc, valor[i]);
}

 

Pois é 🤔 Uma linha.

 

Um programa bem conveniente de teste:

 

Claro que é mais simples digitar direto os números e ler o MDC na hora, então um exemplo seria

 

A saída do exemplo, programa p1

 

toninho@DSK-2009:~/projects/dsp$ ./p1
toninho@DSK-2009:~/projects/dsp$ ./p1 34 17
MDC = 17
toninho@DSK-2009:~/projects/dsp$ ./p1 90 210 100
MDC = 10
toninho@DSK-2009:~/projects/dsp$ ./p1 2 4 6 8 10 12 14
MDC = 2
toninho@DSK-2009:~/projects/dsp$ ./p1 2 4 6 8 10 12 14 13
MDC = 1
toninho@DSK-2009:~/projects/dsp$ 

 

O programa todo, usando C++ mais para C++11 que para C++20 :) , bem conservador:
 

#include <iostream> 
#include <vector>  
using namespace std;

struct MDC
{
    vector<int> valor;
    int         mdc;
    int         Euclides(int, int);

    MDC(const vector<int>&);
};

int main(int argc, char** argv)
{
    vector<int> valor{}; // vazio
    if (argc < 3) return -1;
    for (int i = 1; i < argc; i += 1) valor.push_back(atoi(argv[i]));
    MDC teste(valor);
    cout << "MDC = " << teste.mdc << endl;
    //MDC um_grupo( { 90, 210, 100 });
    //cout << "MDC = " << um_grupo.mdc << endl;
    return 0;
}

MDC::MDC(const vector<int>& valor) : mdc(valor[0])
{
    for (int i = 1; i < (int)valor.size(); i += 1) mdc = Euclides(mdc, valor[i]);
}

int MDC::Euclides(int a, int b)
{   // MDC pelo metodo de Euclides
    int resto;
    while (b != 0)
    {   resto = a % b;
        a = b;
        b = resto;
    }
    return a;
}
// fim

 

O exemplo de antes está comentado para não repetir toda hora :) 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, Midori disse:

Porquê usou mdc(valor[0]) nessa parte? Sem esse comando também rodou

 

Rodar não quer dizer muito.

 

A série começa com o MDC dos dois primeiros. Se você tirar o primeiro e ele for um primo grande vai ver o que vai dar ;) Veja:

trecho.png.53509eb057c9164e4dcbc0d3f82c2853.png

Se ele for um divisor de algum outro não vai fazer diferença...

 

Então, você começa com o primeiro. Ou começa com 1 e faz uma chamada de função a toa. É mais simples assim do que ficar usando dois índices dentro do loop, i e i+1. Entendeu?

Da solução apontada:

 

Em 16/03/2021 às 12:23, Midori disse:

x = mdc(32, 48);
y = mdc(x, 120);

 

É o mesmo resultado de y = mdc(mdc(32, 48), 120);

 

 

 

Revisitando o programa

 

Como eu disse, podia ser um pouco mais curto e legível, ainda no formato '11. O que é comum nesses programas de console é redefinir << para a classe MDC, e assim se pode escrever:
 

int main(int argc, char** argv)
{
    vector<int> valor{}; // vazio
    if (argc < 3) return -1;
    for (int i = 1; i < argc; i += 1) valor.push_back(atoi(argv[i]));
    MDC teste(valor);
    cout << teste;
    return 0;
}


E rodar assim por exemplo
 

toninho@DSK-2009:~/projects/dsp$ g++ -o mdc2 -Wall -std=c++2a -O3 mdc2.cpp
toninho@DSK-2009:~/projects/dsp$ ./mdc2 12 30 36 300
MDC(12,30,36,300) = 6
toninho@DSK-2009:~/projects/dsp$ 

 

Que é bem mais prático porque toda vez que precisar mostrar isso na tela pode usar simplesmente

 

	cout << teste;

 

ou mesmo

 

	cerr << teste;

 

ou qualquer outro output stream aberto.
 

E na hora de mudar a apresentação basta mudar a função.

 

O que mudar para isso?

 

Na classe MDC
 

struct MDC
{
    const vector<int>&    valor;
    int             mdc;
    int             Euclides(int, int);
    MDC(const vector<int>&);
    friend ostream& operator << (ostream& sai, const MDC& m);
};

 

Apenas uma linha, definindo a definição do operador como friend para poder acessar as variáveis da classe.

 

E a função, com 8 linhas

 

ostream& operator << (ostream& sai, const MDC& m)
{
    sai << "MDC(";
    for(int i=0; i< (int) m.valor.size()-1; i+=1 )
        sai << m.valor[i] << ",";
    sai << m.valor[m.valor.size()-1] << ") = " << m.mdc << "\n";
    return sai;
};

 

E a saída continua igual, mas prática: pergunta e resposta, sem prompts intermináveis pelos números ou menus estranhos:

 

toninho@DSK-2009:~/projects/dsp$ g++ -o mdc2 -Wall -std=c++2a -O3 mdc2.cpp
toninho@DSK-2009:~/projects/dsp$ ./mdc2 1 2 3 4
MDC(1,2,3,4) = 1
toninho@DSK-2009:~/projects/dsp$ ./mdc2 200 10 12 24 20
MDC(200,10,12,24,20) = 2
toninho@DSK-2009:~/projects/dsp$ ./mdc2 200 10 120 240 20
MDC(200,10,120,240,20) = 10
toninho@DSK-2009:~/projects/dsp$ 
toninho@DSK-2009:~/projects/dsp$ 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Segue uma solução simples em C

 

#include <assert.h>
#include <stdio.h>

int mdc(int *v, size_t len)
{
    assert(len != 0);

    int ret = v[0];
    for (size_t i = 1; i < len; i++)
    {
        int b = v[i];
        while (b != 0)
        {
            int r = ret % b;
            ret = b;
            b = r;
        }
    }
    
    return ret;
}

int main()
{
    int v[] = { 2, 4, 6, 8, 10, 12, 14 };

    printf("Mdc: %d\n", mdc(v, 7));
    
    return 0;
}

 

Ou para o insano C++

 

#include <iostream>
#include <vector>
#include <cassert>
#include <iterator>

using namespace std;

template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type mdc(Iterator begin, Iterator end)
{
    assert(begin < end);
    using value_type = typename std::iterator_traits<Iterator>::value_type;
    
    Iterator it = begin;
    value_type ret = *it++;

    while(it != end)
    {
        value_type b = *it++;
        while (b != 0)
        {
            value_type r = ret % b;
            ret = b;
            b = r;
        }        
    }
    
    return ret;
}

int mdc(vector<int> v)
{
    mdc(v.begin(), v.end());
}

int main()
{
    std::cout << mdc({2, 4, 6, 8, 10, 12, 14 }) << std::endl;

    return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Revisitando o exemplo: algo um pouco mais compacto e moderno

 

Como o MDC de um grupo de inteiros é

  • por definição associativo e comutativo, porque é uma intersecção entre fatores primos
  • e calculado em sequência pelos pares de produtos como
     
    	MDC(a,b,c,d...) = MDC ( a, MDC( b, MDC(c, ...) ) )

         Como apareceu num exemplo que eu mostrei ontem:
 

MDC::MDC(const vector<int>& valor) : valor(valor), mdc(valor[0])
{
    for (int i = 1; i < (int)valor.size(); i += 1) mdc = Euclides(mdc, valor[i]);
}

 

Então 

 

Nos tempos modernos em que mesmo telefones são octa-core se pode por certo usar de outros recursos.

  • O uso de loops for como esse acima é desencorajados há anos,
  • Alguns algoritmos modernos podem ser paralelizados pelo próprio compilador, sem qualquer alteração de lógica, usando as novas políticas de execução disponíveis no header <execution>  e dar diferenças de tempo de execução de 10 ou 100x às vezes, em máquinas relativamente comuns.
  • lembrando de javascript, C++ tem uma versão sofisticada de reduce() há anos. E é exatamente isso que está escrito acima, já que:
    • o cálculo do mdc é binário, de dois em dois elementos,
    • associativo
    • comutativo
    • e assim pode até ser executado em paralelo

 

Eis uma outra maneira de calcular isso, mais de acordo com os novos tempos, em um exemplo simples que se pode rodar na linha de comando para ter uma resposta imediata

 

A "nova" classe MDC
 

struct MDC
{
    const vector<int>& valor;
    int             mdc;
    MDC(const vector<int>&);
    friend ostream& operator<< (ostream& sai, const MDC& m);
};

 

Só o mínimo: o vetor de valores, o MDC, o operador para mostrar arrumadinho o valor, tipo MDC(a,b,c) = d e o construtor para fazer a conta afinal

 

O método de Euclides para calcular o MDC de 2 valores
 

auto Euclides = [](int a, int b)
{   // MDC pelo metodo de Euclides
    int resto;
    while (b != 0)
    {   resto = a % b;
        a = b;
        b = resto;
    };
    return a;
};

 

O cálculo do MDC pra todo o conjunto é uma operação conhecida como reduce ou fold ou accumulate ou aggregate dependendo da linguagem que se use, e significa executar uma operação com os elementos de uma série e acumular o resultado, em geral uma soma.

 

MDC::MDC(const vector<int>& valor) : valor(valor), mdc(1)
{
    mdc = std::reduce(std::execution::par, valor.begin(), valor.end(), mdc, Euclides);
};

 

Pois é: uma linha só: para todos os elementos do vetor valor acumula em mdc o resultado da operação Euclides. Só isso. 

Compiladores mais antigos podem ter problemas com o std::execution que fiz que pode rodar em paralelo em vários cores os cálculos de mdc, e basta apagar daí, se é que alguém está sequer lendo isso ;) 

 

E main() para um teste?

 

int main(int argc, char** argv)
{
    vector<int>valor{}; // vazio
    if (argc < 3) return -1; // precisa de 2 ao menos
    for (int i = 1; i < argc; i += 1) valor.push_back(atoi(argv[i]));
    MDC teste(valor); // os valores estão todos no vetor 'valor'
    cout << teste;
    return 0;
};

 

6 linhas, e dá pra ler até: pega os valores da linha de comando, coloca no vetor, cria uma MDC com esse vetor e mostra o MDC calculado.

 

Claro que pode declarar vetores de MDC, usar vários deles no mesmo programa, usar ponteiros e alocar novos, e com qualquer tamanho porque vai afinal passar o vetor

 

Esse é só um teste para mostrar algumas possibilidades.

 

Alguns resultados, em Windows
 

18/03/2021  00:05    <DIR>          .
18/03/2021  00:05    <DIR>          ..
18/03/2021  00:05            14.336 chp21-0315-euc.exe
18/03/2021  00:05           708.608 chp21-0315-euc.pdb
18/03/2021  00:05            14.336 fold.exe
18/03/2021  00:05           806.912 fold.pdb
               4 arquivo(s)      1.544.192 bytes
               2 pasta(s)   57.216.790.528 bytes disponíveis

C:\Forum>cd Release

C:\Forum\Release>fold

C:\Forum\Release>fold 4 8 12 16
MDC(4,8,12,16) = 4

C:\Forum\Release>fold 4 8 12 16 7
MDC(4,8,12,16,7) = 1

C:\Forum\Release>fold 4 8
MDC(4,8) = 4

C:\Forum\Release>fold 4 5 6
MDC(4,5,6) = 1

C:\Forum\Release>fold 22 121
MDC(22,121) = 11

C:\Forum\Release>

 

Claro, fold.exe é o programa

 

E o programa de teste todo?

 

O programa só faz isso: aceita os números todos na linha de comando, mostra o resultado. É só para testar a struct MDC.

 

Eis o código
 

#include <execution> 
#include <iostream> 
#include <vector>  
using namespace std;

struct MDC
{
    const vector<int>& valor;
    int             mdc;
    MDC(const vector<int>&);
    friend ostream& operator<< (ostream& sai, const MDC& m);
};

auto Euclides = [](int a, int b)
{   // MDC pelo metodo de Euclides
    int resto;
    while (b != 0)
    {   resto = a % b;
        a = b;
        b = resto;
    };
    return a;
};

int main(int argc, char** argv)
{
    vector<int>valor{}; // vazio
    if (argc < 3) return -1; // precisa de 2 ao menos
    for (int i = 1; i < argc; i += 1) valor.push_back(atoi(argv[i]));
    MDC teste(valor); // os valores estão todos no vetor 'valor'
    cout << teste;
    return 0;
};

MDC::MDC(const vector<int>& valor) : valor(valor), mdc(0)
{
    mdc = std::reduce(std::execution::par, valor.begin(), valor.end(), mdc, Euclides);
};

ostream& operator << (ostream& sai, const MDC& m)
{
    sai << "MDC(";
    for (int i = 0; i < (int)m.valor.size() - 1; i += 1)
        sai << m.valor[i] << ",";
    sai << m.valor[m.valor.size() - 1] << ") = " << m.mdc << "\n";
    return sai;
};

 

Podia ter metade do tamanho, mas ia ficar difícil de ler e seria frescura 🤔 ou teimosia. Não precisa da struct nem da função Euclides nem do operador <<: podia só colocar o cálculo em main() e testar direto. 

 

Compilei em MSVC , 19.28. mas pode servir algo bem mais antigo. Em gcc ou clang pode-se ter problemas com as versões antigas. Deve rodar igual em clang 10 ou gcc 9. 

 

Claro, não testei quase nada :D

 

 

 

 

 

 

 

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

19 horas atrás, arfneto disse:

Podia ter metade do tamanho

 

Apenas criando um vetor em torno dos dados e retornando o MDC direto, como nesse foldmin.exe
 

...

18/03/2021  19:19    <DIR>          .
18/03/2021  19:19    <DIR>          ..
18/03/2021  00:05            14.336 chp21-0315-euc.exe
18/03/2021  00:05           708.608 chp21-0315-euc.pdb
18/03/2021  18:57            16.384 fold.exe
18/03/2021  18:57           905.216 fold.pdb
18/03/2021  19:21            13.824 foldmin.exe
18/03/2021  19:21           823.296 foldmin.pdb
               6 arquivo(s)      2.481.664 bytes
               2 pasta(s)   58.291.949.568 bytes disponíveis

C:\Teste\Release>foldmin

C:\Teste\Release>foldmin 2 3
MDC = 1

C:\Teste\Release>foldmin 20 32 8
MDC = 4

C:\Teste\Release>

 

Eis o código

 

#include <iostream> 
#include <numeric> 
#include <vector>  
using namespace std;

int main(int argc, char** argv)
{
    vector<int> valor{}; // vazio
    int mdc = 0;
    if (argc < 3) return -1; // precisa de 2 ao menos
    for (int i = 1; i < argc; i += 1) valor.push_back(atoi(argv[i]));
    mdc = std::reduce(valor.begin(), valor.end(), mdc,
        [](int a, int b)
        {   // MDC pelo metodo de Euclides
            int resto;
            while (b != 0)
            {   resto = a % b;
                a = b;
                b = resto;
            };
            return a;
        });
    cout << "MDC = " << mdc << endl;
    return 0;
};

 

 

Apenas umas 6 linhas além de uma implementação do método de Euclides para calcular o MDC entre dois números.

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Para entrar com a quantidade desejada de números e o loop terminar quando a entrada for igual 0,

 

#include <iostream>
#include <vector>
using namespace std;

int mdc(vector<int> &v){
    int a = v[0];
    for(auto num : v){
        int b = num;
        while(b != 0){
            int resto = a % b;
            a = b;
            b = resto;
        }
    }
    return a;
}

int main(){
    vector<int> v;
    int n;
    
    do{
        cout << ": ";
        cin >> n;
        v.push_back(n);
    }while(n);
    cout << "MDC = " << mdc(v) << endl;
    return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

34 minutos atrás, Midori disse:

Para entrar com a quantidade desejada de números e o loop terminar quando a entrada for igual 0

 

@Midori Não acha muito mais simples usar a linha de comando como eu mostrei nos 3 ou 4 exemplos acima? Em especial em um programa que calcula uma única série?

 

Qual a vantagem de abrir o programa e DEPOIS ficar digitando os números, e um por vez? 

 

Podia ao menos ler uma linha toda deles e ajudar um pouco...

 

Considerando duas opções do programa mdc.exe ;) 

  • opção A
    • mdc<enter>
    • 10<enter>
    • 20<enter>
    • 30<enter>
    • 40<enter>
    • 50<enter>
    • 60<enter>
    • 0<enter>
    • e o programa responde MDC = 10
       
  • Opção B
    • mdc<enter>
    • 10 20 30 40 50 60 <enter>
    • o programa responde MDC = 10

 

  • Opção C
    • mdc 10 20 30 40 50 60 <enter>
    • o programa responde MDC = 10

Essa última é a opção clássica desde os anos 70. Imagine se tivesse que chamar o compilador, por exemplo, e DEPOIS ele responder e aí você digitar as opções e o nome do programa a compilar....

Se considerar o último exemplo que mostrei:

  • sendo o mdc() associativo e comutativo, como você exemplificou em outro tópico
  • sendo o vetor iterável por definição

Pode apenas usar, a la javascriptreduce() em uma linha, como eu mostrei no tópico acima, em uma linha só, trocando em seu programa

 

	cout << "MDC = " << mdc(v) << endl;

 

por
 

	cout << "MDC = " << (n = std::reduce(valor.begin(), valor.end(), n, mdc) ) << endl;

 

C++ não é C. C não é C++.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

9 horas atrás, arfneto disse:

Não acha muito mais simples usar a linha de comando como eu mostrei nos 3 ou 4 exemplos acima? Em especial em um programa que calcula uma única série?

Usei um compilador online e da forma que fez não dá para testar e ver o resultado, mas é mais simples sim usar a linha de comando como mostrou.

 

9 horas atrás, arfneto disse:

Pode apenas usar, a la javascriptreduce() em uma linha, como eu mostrei no tópico acima, em uma linha só, trocando em seu programa

Tentei rodar seu último código e deu este erro,

 

main.cpp:12:16: error: ‘reduce’ is not a member of ‘std’

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Midori disse:

Usei um compilador online e da forma que fez não dá para testar e ver o resultado, mas é mais simples sim usar a linha de comando como mostrou.


 

Não tenho nenhuma experiência com compiladores online exceto claro o compiler explorer de Matt Godbolt, mas nunca usei nem esse para rodar programas de verdade. Apenas para comparar o código gerado em vários compiladores.

 

Eu não usaria algum compilador que não tivesse essa opção de usar a linha de comando se fosse rodar meus programas ou postar algo para iniciantes. A maioria dos programas para iniciantes é baseada na linha de comando, programas para console como esse aqui. E não usar os argumentos da linha de comando é uma limitação besta devido ao modo besta como ensinam a programar em geral ( minha opinião, num forum público).

 

É um desperdício. Imagine como seria se o compilador não usasse argumentos por exemplo...

 

No entanto mesmo o próprio compiler explorer pode aceitar isso, com descrito em https://reposhub.com/cpp/cli/ethanhs-cce.html. Claro, nunca usei.

 

Numa rápida pesquisa vi que JDoodle aceita argumentos. Pode tentar esse... Veja
 

image.png.54dfc493ccd34bddf04074cde71c0c04.png

 

 

3 horas atrás, Midori disse:

Tentei rodar seu último código e deu este erro,

 

main.cpp:12:16: error: ‘reduce’ is not a member of ‘std’

 


Deve imaginar que o código não está errado, já que no tópico está o resultado da execução e em  quase todos os exemplos que eu posto está a linha de compilação, como essa no tópico #9. 

 

Em 17/03/2021 às 10:40, arfneto disse:

toninho@DSK-2009:~/projects/dsp$ g++ -o p1 -Wall -std=c++2a -O3 mdc.cpp
toninho@DSK-2009:~/projects/dsp$ ./p1
MDC = 10
toninho@DSK-2009:~/projects/dsp$ 

 


E reduce() é um paradigma importante e moderno. Se usa em muitas linguagens, em especial na web, pelo óbvio poder disso: combinar dados . E em modelos de computação distribuída. 

 

Não ficou claro em meu exemplo, mas se usar as políticas de execução --- #include <execution> --- em um compilador moderno ele vai distribuir os cálculos dos MDC por todos os cores da máquina, rodando talvez 10 ou 100 ou milhares de vezes mais rápido que um programa comum para um número grande de pares. reduce() é paralelizável. Sózinho, basta mudar o primeiro argumento. Esse modelo é usado pelo Google por exemplo, para distribuir consultas entre milhares de CPUs. Sobre isso veja off-topic, mas relevante sobre Design Patterns

 

Esse exemplo é um programa de 25 linhas... Deve rodar sem alterações em Linux ou Windows ou Mac em clang ou gcc ou msvc. Usei o último nesse caso.

 

A título de curiosidade, em Ubuntu 20:
 

toninho@DSK-2009:~/projects/dsp$ g++ -o teste -Wall -O3 -std=c++17 teste.cpp
toninho@DSK-2009:~/projects/dsp$ ./mdc 10 20 32 40 50 60 70 
MDC = 2

 

E roda sem problemas. 
 

3 horas atrás, Midori disse:

Usei um compilador online e da forma que fez não dá para testar e ver o resultado, mas é mais simples sim usar a linha de comando como mostrou

 

Mesmo com a limitação de seu compilador online --- recomendo procurar outro --- note que fazer o infeliz usuário digitar os argumentos um por um como fez, ao invés de ler todas na mesma linha, é cruel. demais Imagine o exemplo acima, ou o que eu expliquei antes:
 

12 horas atrás, arfneto disse:

Considerando duas opções do programa mdc.exe ;) 

  • opção A
    • mdc<enter>
    • 10<enter>
    • 20<enter>
    • 30<enter>
    • 40<enter>
    • 50<enter>
    • 60<enter>
    • 0<enter>
    • e o programa responde MDC = 10
       
  • Opção B
    • mdc<enter>
    • 10 20 30 40 50 60 <enter>
    • o programa responde MDC = 10

 

  • Opção C
    • mdc 10 20 30 40 50 60 <enter>
    • o programa responde MDC = 10

 

E se o cara errar um número já era.

 

Ao menos use a opção B. Você não iria gostar de usar seu programa... E programas são escritos para serem usados, não apenas "entregues".

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...