1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

[Ajuda] Programa (simples) em C

Discussão em 'Programação' iniciada por RuiSilvaMC, 17 de Janeiro de 2009. (Respostas: 21; Visualizações: 1176)

  1. Boa noite pessoal, precisava da vossa ajuda. Eu estou a dar os meus primeiros passos em C, estou a fazer exercícios básicos ainda, contudo tenho uma duvida neste programa:

    /* Elabore um programa que gere os numeros do totoloto*/

    #include <iostream>
    #include <ctime>
    using namespace std;
    int main ()
    {
    int i, bola;
    srand((unsigned) time (NULL));
    for (i=1;i<7;i++){
    bola = rand()%49+1;
    cout << "O numero da bola e o " << bola<< '\n';
    }
    }


    Ele funciona, mas tem um problema, imaginemos que a primeira bola é a bola 29, essa bola nao deveria voltar a sair, mas tal como o programa está feito isso acontece, gostava de saber o que acrescentar para que ele não repetisse a mesma bola duas vezes. Eu já tentei "inventar" algumas coisas mas não resultou. LOL. Podem-me ajudar?

    Obrigado pela atenção.
     
  2. Evil_Tidus

    Evil_Tidus Power Member

    terias que armazenar o valor que saísse num array de 7 posições e a cada inserção verificasse se ja haveria algum valor repetido
     
  3. Evil Tidus, podes-me explicar como se faz isso? Eu ainda estou a aprender e a ler sobre C. Podes exemplificar? Quem em deu o exercício disse que este erro pode ser ultrapassado com apenas duas linhas de código usando vectores ou algo do género, mas eu não estou a conseguir lá chegar..
     
  4. Aparicio

    Aparicio /dev/mod
    Staff Member

    Poderias fazer com um array (ou vector, é a mesma coisa) com as 6 posições, mas depois precisas de um ciclo extra para ver se a bola existia nesse array.

    Outra forma pode ser, começas por declarar um vector com 50 posições a zero, uma para cada bola.
    Depois no ciclo for, por exemplo sai-te a bola 12, se xpto[12] for igual a 1 é porque já te saiu essa bola e não contas essa, se for igual a 0, poes o xpto[12] a 1 e contas como uma bola que ainda não saiu.
     
  5. Aparicio, eu percebi o teu raciocínio, mas como escrevias isso em c?
     
  6. Aparicio

    Aparicio /dev/mod
    Staff Member

    Estás a fazer isso em C ou C++? É que essas bibliotecas são de C++.

    Em C puro e sem grandes complicações faria assim:
    Código:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    int main (void)
        {
        int i = 1, bola, xpto[51];
        memset( xpto, 0, 51 * sizeof(int) ); // Faz o mesmo que um ciclo que pusesse
                                             // todos os valores do array a zero
        srand((unsigned) time (NULL));
        
        while( i < 7 )
            {
            bola = rand() % 49 + 1;
            
            if( xpto[bola] == 0)
                {
                printf("O numero da bola e o %d\n", bola);
                xpto[bola] = 1;
                i++;
                }
            }
        return 0;
        }
     
    Última edição: 18 de Janeiro de 2009
  7. Aparicio

    Aparicio /dev/mod
    Staff Member

    Então, é só pegares na ideia do que eu fiz e passares para C++;
     
  8. Eu tou a tentar. Obrigado Aparicio. =)

    Mas não estou a conseguir fazer a conversão, o que significa "%d\n" e a xpto[51]?

    EDIT: Em principio só vou poder responder a este tópico para a semana. Depois eu digo alguma coisa, fiquem bem e obrigado aos dois por me terem ajudado. Acho que consegui o que queria. Abraço.
     
    Última edição: 18 de Janeiro de 2009
  9. %d significa que o algarismo é inteiro. Por exemplo: printf("O número é %d.", a); em que 'a' é um algarismo do tipo int. xpto[51] é o valor armazenado na posição 51 do vector xpto.

    Corrijam-me se estiver enganado. Também sou noob nisto. :D
     
  10. AliFromCairo

    AliFromCairo Power Member

    Na verdade, é a dimensão do array. Mas enfim, é o que dá utilizar números mágicos.
     
  11. beat-

    beat- Power Member

    Código:
    #include <vector>
    #include <iostream>
    #include <ctime>
    
    vector<bool> inicializaVector()
    {
        vector<bool> numerosSaidos;
        for(int i=0; i<50; i++)
            numeros.push_back(false);
    
        return numerosSaidos;
    }
    
    
    int main()
    {
    	vector<bool> numerosSaidos = inicializaVector();
    	srand((unsigned) time (NULL));
    
    	for(int i=1;i<7;i++)
    	{
    		bola = rand()%49+1;
    		if(numerosSaidos[bola] == TRUE)
    			i--;
    		else
    		{
    			cout << "O numero da bola e o " << bola<< '\n';
    			numerosSaidos[bola] = TRUE;
    		}
    	}
    	
    	return 0;
    }
    
    Não testei.
     
    Última edição: 25 de Janeiro de 2009
  12. blueomega

    blueomega Power Member

    porque é que inicializas 50 posições pra guardar 7

    gastas menos memoria a inicializar as 7 posições e o algoritmo passar de n pra n^2 neste caso não é propriamente muito negativo
     
  13. IComeFromBehind

    IComeFromBehind Power Member

    Mais uma implementação:

    Código:
    #include <iostream>
    #include <algorithm>
    #include <numeric>
    #include <vector>
    #include <iterator>
    #include <stdlib.h>
    
    int main() {
        std::vector<int> available_numbers;
      
        for(size_t i = 1; i < 51; i++)
            available_numbers.push_back(i);
    
        srand((unsigned) time(NULL));
        std::random_shuffle(available_numbers.begin(), available_numbers.end());
    
        std::ostream_iterator<int> output(std::cout, " ");
      
        std::cout << "Numeros sorteados: ";
        std::copy(available_numbers.begin(), available_numbers.begin() + 7, output);
        std::cout << std::endl;
    
        return 0;
    }
    
    
     
    Última edição: 26 de Janeiro de 2009
  14. Aparicio

    Aparicio /dev/mod
    Staff Member

    Isso depois dependo do que se quer, menos memória em mais tempo ou o contrário, mas se criares um array de 7 posições, depois para cada número que geras tens estar a percorrer o array para ver se o número já existe, não é muito elegante a meu ver.
    A forma ideal seria utilizar um tipo lista, de forma a que se retirava literalmente os números da lista de forma a nunca saírem repetidos, mas para isto era preciso estar a implementar o tipo lista.
     
  15. beat-

    beat- Power Member

    Depende do que queres, maior performance ou menor gasto de recursos.
    De qualquer forma um bool ocupa apenas um bit portanto o uso de memória não é nada excessivo.
     
  16. blueomega

    blueomega Power Member

    neste caso não é algo que se tenha que preocupar, eu sou apologista de guardar apenas o essencial, discartando tudo que é redundante ou possivel de recalcular, isto na maioria dos casos

    apesar de ser bool (0 ou 1) o tamanho de 1 bool não é um bit, mas sim um byte (na maioria dos compiladores), o int é 4 bytes

    neste caso o array tem 50 bytes com acesso O(1)

    a minha versão tinha 28 bytes (7*4 bytes) e apesar de ter que correr mais umas vezes o array (linearmente contra acesso directo do caso dos 50 bytes)

    Aparicio podes sempre correr da posição inicial até apenas i
     
  17. Aparicio

    Aparicio /dev/mod
    Staff Member

    Embora um bool deveria ocupar apenas um bit, na prática ocupa um byte, pelo menos em C.
    Utilizando o stdbool.h, sizeof(bool) retorna 1 (byte).

    Arranjei outra forma de resolver o problema, em que nem é preciso um array enorme nem percorrer o array várias vezes. Considerando o array como uma string e utilizando o strchr para ver se a bola já existe na string.

    Código:
    #include <stdio.h>
    
    void aleat( char *xpto, int n, int min, int max )
        {   
        *xpto = rand() % max + min;
        if( n > 1 )
            do aleat( xpto+1, n-1, min, max );
                while( strchr( xpto+1, *xpto ) );
        }
    
    int main(void)
        {    
        srand((unsigned) time (NULL));
           
        char xpto[8];
        memset( xpto, 0, 8);
        
        aleat( xpto, 7, 1, 50 );
        
        int x;
        for( x = 0; xpto[x] != 0; x++)
            printf("O numero da bola e o %d\n", xpto[x] );
        
        getchar();
        return 0;
        }
     
  18. blueomega

    blueomega Power Member

    bom exemplo de uso da recursividade e apontador
     
  19. IComeFromBehind

    IComeFromBehind Power Member

    Só uma questão, o algoritmo recursivo não é péssimo? Uma repetição de um número aleatório faz com que se gere uma sequência completa.
     

Partilhar esta Página