Ir ao conteúdo
  • Cadastre-se

C Preenchimento de valor aleatorio a vetor em C


alan.modesto
Ir à solução Resolvido por devair1010,

Posts recomendados

Boa noite, Consigo preencher um valor aleatorio a um vetor, mas na hora de utilizar meu codigo da erro em algum ponto que eu não consigo saber e nem o porque. alguém pode me alertar pelo menos onde é? cheguei a localizaçao da funçao exibir, mas o que acontece lá e porque la ainda não sei. Segue o ocodigo:

planejo com este: Desenvolver uma função que percorrerá os
elementos de vetorX na ordem definida em
vetX1.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TAM 3

/*void preencherAleatorio (int vetor[], int tamanho)
{
    //declaração de variáveis
    int i, igual , j;


    srand(time(NULL));

    do{ // faça
        vetor[i] = rand() % tamanho; // sorteia um número
        igual = 0;
        for(j = 0; j < i; j++){ // percorre a parte do vetor já preenchida
            if(vetor[j] == vetor[i])
                igual = 1; // número repetido
        }

        if(igual == 0) // significa que o elemento não se repetiu
            i++;
    }while(i < tamanho); // enquanto não for sorteado TAM números diferentes

    for(i = 0; i < tamanho; i++){
        printf("%d ", vetor[i]);
    }
    printf("\n\n");
}*/
//implementação das funções
int exibirVetor (int vetor[], int tamanho, int vetor1[])
{
    //declaração de variáveis
    int i, j,cont = 0;

// passando um vetor dentro de outro para seguir ordem de posiçao
    printf ("\nVetor: ");

    for (i=0 ;i<tamanho;i++)
    {
    if(vetor1[vetor[i]] <= vetor1[vetor[i+1]]){
      cont++;
    }
        printf ("%d ", vetor1[vetor[i]]);
    }
    // 1 para crescente, 0 para não crescente
    if( cont == tamanho-1){
    return 1;
  }else{
    return 0;
  }
    printf ("\n\n");
}

int main(void) {
   int A[TAM] = {5,10,11}    ;
    int B[TAM] = {2,1,0} ; // usando um B pré ordenado para testar
  int C[TAM];
  int resp;

preencherAleatorio(C, TAM);
  resp = exibirVetor(C, TAM, A);
  printf ("\nVetor: %d ", resp);
    return 0;
}

 

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

  • Solução

@alan.modesto     você não disse que erro que dá , mas aqui no codeblocks , não deu nenhum erro , não , apenas também não fez nada ,  e  mostrou uma tela toda preta , 

cb3.thumb.jpg.fdcc0a0061f7f4b1828b2b513e1b1cd3.jpg

mas ele não funciona por que você não inicializou a variável "i"  , assim o valor é desconhecido e o compilador termina a execução para não gravar dados em local que não pode ,  e acertando isso ,  seria assim 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TAM 3
void preencherAleatorio (int vetor[], int tamanho)
{
  //declaração de variáveis
  int i     = 0;
  int igual = 0;
  int j     = 0;
  do  // faça
  {
    vetor[i] = rand() % tamanho; // sorteia um número
    igual = 0;
    for(j = 0; j < i; j++)  // percorre a parte do vetor já preenchida
    {
      if(vetor[j] == vetor[i])
        igual = 1; // número repetido
    }
    if(igual == 0) // significa que o elemento não se repetiu
      i++;
  } while(i < tamanho);  // enquanto não for sorteado TAM números diferentes

  for(i = 0; i < tamanho; i++)
  {
    printf("%d ", vetor[i]);
  }
  printf("\n\n");
}
//implementação das funções
int exibirVetor (int vetor[], int tamanho, int vetor1[])
{
  //declaração de variáveis
  int i, j,cont = 0;

// passando um vetor dentro de outro para seguir ordem de posiçao
  printf ("\nVetor: ");

  for (i=0 ; i<tamanho; i++)
  {
    if(vetor1[vetor[i]] <= vetor1[vetor[i+1]])
    {
      cont++;
    }
    printf ("%d ", vetor1[vetor[i]]);
  }
  // 1 para crescente, 0 para não crescente
  if( cont == tamanho-1)
  {
    return 1;
  }
  else
  {
    return 0;
  }
  printf ("\n\n");
}

int main(void)
{
  srand(time(NULL));
  int A[TAM] = {5,10,11}    ;
  int B[TAM] = {2,1,0} ; // usando um B pré ordenado para testar
  int C[TAM];
  int resp;

  preencherAleatorio(C, TAM);
  resp = exibirVetor(C, TAM, A);
  printf ("\nVetor: %d ", resp);
  return 0;
}

 

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

int main(void) {
   int A[TAM] = {5,10,11}    ;
   int B[TAM] = {2,1,0} ; // usando um B pré ordenado para testar
   int C[TAM];

 

Não é preciso colocar o tamanho se vai declarar todos os valores. Prefira

 

int main(void) {
   int A[] = {5,10,11};
   int B[] = {2,1,0} ; // usando um B pré ordenado para testar
   int C[] = {0};// todos em zero

 

Sobre o valor aleatório não está bom. Já assistiu um sorteio da loto? Já jogou bingo?

 

Você não sorteia os números. Nunca. Sorteia as posições.

 

Veja como começa um sorteio:  o de 26/11/2022, hoje por exemplo... https://youtu.be/pWNVqCEwkbI?t=517 

 

Começa com a mala com as bolinhas. TODAS as bolinhas são iguais. Idênticas, perfeitamente esféricas e com números pintados com tinta do mesmo peso e são perfeitamente balanceadas. E vem um auditor e rompe o lacre.

 

É assim que funciona. Na literatura dizem que é um algoritmo e tem o nome de dois caras, Fisher e Yates. Masacho uma bobagem. A primeira vez em que eu programei isso eu tinha 14 e só fiz assim porque era o óbvio. Eis o tal "algoritmo" para 60 números da mega-sena:

  • São bolinhas numeradas de 1 a 60 e vem na mala lacrada
  • Vão todas para um único globo
  • O globo gira, tem um furo onde encaixa uma única bolinha
  • O globo para e com o peso embaixo a bolinha fica presa lá
  • o cara aperta o gatilho e a bolinha cai
  • o cara mostra o número para todo mundo e põe a bolinha numa canaleta 
  • o cara gira o globo mais 5 vezes e assim tem as 6 dezenas sorteadas.

É claro que não vai repetir porque no bingo as bolinhas não voltam para o globo. Esse é o erro de todo mundo que programa isso, ao que parece. É como as cartas o poker: não tem como repetir porque elas estão na mesa ou na mão de alguém. Esse é o erro desses programas: a ideia ingênua de sortear números de 1 a 60 por exemplo...E depois de sortear ficar testando pra ver se já tinha saído... E sempre sortear entre todas as bolinhas. Seria como o bingo da igreja colocar a bolinha de volta no globo. PARA QUE?? A cada sorteio tem uma bolinha a menos até ter 2 bolinhas, já que com uma só o sorteio é fácil: ELA, a única e última ou primeira 😉 

 

Como fazer então, e em C? Exemplo como a mega-sena loteria da CEF com bolinhas numeradas de 1 a 5 inclusive e sorteando 3 números

 

Apenas numere as bolas como o bingo. De qualquer jeito. O óbvio: numeradas. Como o bingo.

 

Um vetor. Só isso.

 

para 5 bolinhas:

 

	int T = 5; // total	T
	int N = T; // N faltam
	int bola[] = { 1,2,3,4,5 };

 

E antes de tudo como estão?

 

// as bolas inicialmente
	printf("Bolas no inicio: ");
	for (int i = 0; i < T; i += 1) printf("%d ", bola[i]);
	printf("\n");

 

E vai mostrar o que?

 

Bolas no inicio: 1 2 3 4 5

 

Sorteia 1 das 5 bolas

 

	int qual = rand() % N;

 

É só isso. Mas não tem a canaleta pra bolinha cair do globo como na CEF ou no bingo. 

 

Então faz o simples: coloca no fim ou no começo do vetor e diminui o número de bolas...

 

	// poe no fim: bola 1
	int temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N-1]);

 

E vai mostrar o que?
 

Bola: 2

 

claro que é aleatório então pode ser qualquer valor entre 1 e 5 porque é a posição do vetor e não o valor que é sorteado. Esse é o erro comum de programas como esse. Deve ser pela falta de jogar bingo e pela ansiedade em escrever código em C ou Pascal ou Python ou FORTRAN ou sei lá em quantas linguagens já vi isso

 

E agora?

 

Já diminuiu o valor de N então é só fazer a mesma coisa e sortear uma das 4 bolinhas que sobrou...

 

	// poe no fim: bola 2
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

 

E mostra nesse exemplo

 

Bola: 4

 

 

Então no final do vetor tem as bolas 4 e 2. E tem ainda 3 bolinhas pra sortear

 

Então

 


	// poe no fim: bola 3
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

	// poe no fim: bola 4/5
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

 

Isso sorteia uma das 3 bolas e depois uma das 2 últimas.

 

O que mostrou?
 

Bola: 5
Bola: 1

 

E agora? Dá claro pra imaginar como ficou o vetor já que a lista de bolas sorteadas está bem aí, mas é melhor conferir

 

	printf("Bolas ao final: ");
	for (int i = 0; i < T; i += 1) printf("%d ", bola[i]);
	printf("\n");

	return 0;

 

E vem 

 

Bolas: 3 1 5 4 2

 

E é só isso.

 

Quer sortear 3 bolas? Pegue as 3 primeiras. 3 1 5

 

O programa todo
 

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	int T = 5; // total	T
	int N = T; // N faltam
	int bola[] = { 1,2,3,4,5 };

// as bolas inicialmente
	printf("Bolas no inicio: ");
	for (int i = 0; i < T; i += 1) printf("%d ", bola[i]);
	printf("\n");

	int qual = rand() % N;

	// poe no fim: bola 1
	int temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N-1]);

	// poe no fim: bola 2
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

	// poe no fim: bola 3
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

	// poe no fim: bola 4/5
	N -= 1;
	qual = rand() % N;
	temp = bola[N - 1];
	bola[N - 1] = bola[qual];
	bola[qual] = temp;
	printf("Bola: %d\n", bola[N - 1]);

	printf("Bolas ao final: ");
	for (int i = 0; i < T; i += 1) printf("%d ", bola[i]);
	printf("\n");
	return 0;
};

 

E uma saída

 

Bolas no inicio: 1 2 3 4 5
Bola: 2
Bola: 4
Bola: 5
Bola: 1
Bolas ao final: 3 1 5 4 2

 

Com 4 sorteios para 5 bolas. Mas se fossem 5000 seriam 4999 sorteios porque os números não voltam para o globo...

 

Note que  o programa não tem nenhum loop nem função nem nada. É uma prova de conceito e rodou assim na primeira vez. É o simples: escrever em torno dos dados.

 

 

É claro que se sair a última bola não precisa inverter

 

E claro que seria bom ter uma semente conhecida chamando srand() no inicio do programa. Em geral eu uso AAAAMMDD a data

 

É claro que isso devia estar em uma struct com o tamanho do vetor e o endereço

 

E isso não é importante. Importante é começar a testar em minutos e não voltar atrás. Não perder tempo

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

De todo modo imagino que essa seja uma versão do tal algoritmo Fisher-Yates. Se eu tivesse um desses sobrenomes ia achar meio pedante ter meu sobrenome numa coisa tão simples e intuitiva. Ninguém no Bingo fala que está usando o algoritmo de Fisher-Yates. Da primeira vez que programei isso eu não sabia nem o que era um algoritmo ou que eles podiam ter nomes 😄 

 

Seguindo com o exemplo

 

O programa que eu mostrei serve como prova de conceito, pra ver se serve. Sem loop sem nada. Para testar em minutos e entender o mecanismo. É melhor escrever assim. Nunca um programa de 300 linhas com menu e interface e

tal.

 

Está claro agora que sorteia um número entre os possíveis, que estão no globo por exemplo. E continua até terem apenas dois. Então por isso se garante um número fixo de sorteios. 52 cartas no deck, 51 sorteios para embaralhar. Não tem sentido sortear sempre dos 52 e ver DEPOIS se repetiu. Por alguma razão quase todo mundo faz assim. Como o programa original desse tópico.

 

UM EXEMPLO MAIS COMPLETO, escrevendo em torno dos dados

 

typedef struct
{
  unsigned qtd;  // total
  int* V;        // o resultado
} Bloco;

 

Esse bloco é o simples container para um vetor de int de tamanho qtd e vou usar no exemplo para um sorteio da mega-sena e um deal de poker, texas holden com 4 jogadores, flop (3), turn (1) e river (1), as 5 cartas que ficam na mesa

 

Bloco* mix(unsigned t) {
  if (t == 0)
    return NULL;  // vai que...
  Bloco* novo = (Bloco*)malloc(sizeof(Bloco));
  if (novo == NULL)
    return NULL;  // deu pau
  novo->qtd = t;
  novo->V = (int*)malloc(t * sizeof(int));
  if (novo->V == NULL) {
    free(novo);
    return NULL;  // deu pau
  }
  for (unsigned i = 0, val = 0; i < t; ++i)
    novo->V[i] = ++val;
  for (unsigned N = t; N > 1; --N) {
    unsigned b = rand() % N;
    int temp = novo->V[N - 1];
    novo->V[N - 1] = novo->V[b];
    novo->V[b] = temp;
  }
  return novo;
};

 

Essa função mix() retorna um Bloco com os números emvaralhados. O simples. E serve para qualquer coisa

 

Eis main() no exemplo

 

int main(void)
{
  srand(20221125);
  Bloco* B = mix(60);
  mostra(B, "\nteste com 60 numeros (Mega-Sena)\n");
  mega(B);
  B = apaga(B);

  Bloco* deck = mix(52);
  mostra(deck, "\nteste com 52 (baralho)\n");
  texas_holden(deck);
  deck = apaga(deck);

  return 0;
};

 

E é fácil de entender. imagino. mix(60) traz um vetor de 60 números e pode ser usado na loteria, mix(52) embaralha 52 cartas. O simples.

 

mega() pega o bloco e pega 6 números para o sorteio.

texas_holden() pega um bloco e dá cartas para 4 jogadores e mostra as cartas do flop.

 

E é claro que tanto faz o que está sorteando. Podiam ser 5000 amostras com 4999 sorteios.

 

Eis a saída

 

teste com 60 numeros (Mega-Sena)
Bloco com 60 elementos

  55    43    24     5    21    12    20     9    19    58
  56    37    23    15     2    47    34    16    31    45
  51    59     1     8    52    17    35    53    27     6
  36    11    32    44    13     7    29    39     4    49
   3    42    30    28    46    48    38    18    54    41
  60    14    50    33    57    26    22    10    40    25


Um sorteio: 55  43  24  05  21  12

apagando bloco com 60 elementos

teste com 52 (baralho)
Bloco com 52 elementos

  10     5    45     1    41    23    12    34    15     8
  51    22    49     9    43     2    11    14    27    31
  38    40    29    39    37    28    32    35    47    46
   3    20    36    19     4    13    42    50    26    25
  52     7    30    18    21    24    33    48    16    44
  17     6

Jogador 1
  Dama de ouros
  Sete de ouros

Jogador 2
  Oito de paus
  Tres de ouros

Jogador 3
  Quatro de paus
  Dama de espadas

Jogador 4
  As de ouros
  Dez de copas

Flop
  Quatro de espadas
  Dez de ouros
  As de paus

Turn
  Valete de espadas

River
  Dama de paus


apagando bloco com 52 elementos

 

E o "programa" todo

 

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  unsigned qtd;  // total
  int* V;        // o resultado
} Bloco;

Bloco* apaga(Bloco*);             // apaga um bloco
int mega(Bloco*);                 // exemplo 1
Bloco* mix(unsigned);             // retorna um sorteio
int mostra(Bloco*, const char*);  // mostra na tela o bloco
int texas_holden(Bloco*);         // exemplo 1

int main(void)
{
  srand(20221125);
  Bloco* B = mix(60);
  mostra(B, "\nteste com 60 numeros (Mega-Sena)\n");
  mega(B);
  B = apaga(B);

  Bloco* deck = mix(52);
  mostra(deck, "\nteste com 52 (baralho)\n");
  texas_holden(deck);
  deck = apaga(deck);

  return 0;
};

Bloco* apaga(Bloco* bl) {
  if (bl == NULL)
    return NULL;
  printf("apagando bloco com %d elementos\n", bl->qtd);
  free(bl->V);
  free(bl);
  return NULL;
}

int mega(Bloco* B) {
  printf("\nUm sorteio: ");
  for (int i = 0; i < 6; i += 1)
    printf("%02d  ", B->V[i]);
  printf("\n\n");
  return 0;
};

Bloco* mix(unsigned t) {
  if (t == 0)
    return NULL;  // vai que...
  Bloco* novo = (Bloco*)malloc(sizeof(Bloco));
  if (novo == NULL)
    return NULL;  // deu pau
  novo->qtd = t;
  novo->V = (int*)malloc(t * sizeof(int));
  if (novo->V == NULL) {
    free(novo);
    return NULL;  // deu pau
  }
  for (unsigned i = 0, val = 0; i < t; ++i)
    novo->V[i] = ++val;
  for (unsigned N = t; N > 1; --N) {
    unsigned b = rand() % N;
    int temp = novo->V[N - 1];
    novo->V[N - 1] = novo->V[b];
    novo->V[b] = temp;
  }
  return novo;
};

int mostra(Bloco* B, const char* msg) {
  const unsigned n_col = 10;
  if (B == NULL)
    return -1;
  if (msg != NULL)
    printf("%s", msg);
  printf("Bloco com %lu elementos\n\n", B->qtd);
  for (unsigned i = 0, col = 0; i < B->qtd; ++i) {
    printf("%4d  ", B->V[i]);
    if (++col == n_col) {
      printf("\n");
      col = 0;
    }
  };
  printf("\n");
  return 0;
};

int texas_holden(Bloco* deck) {
  const char* naipe[] = {"ouros", "espadas", "copas", "paus"};
  const char* face[] = {"Dois", "Tres", "Quatro", "Cinco", "Seis",
                        "Sete", "Oito", "Nove",   "Dez",   "Valete",
                        "Dama", "Rei",  "As"};
  int t = 0;

  // as cartas para alguns jogadores
  for (int player = 0; player < 4; ++player) {
    printf("\
\n\
Jogador %d\n\
  %s de %s\n", (1+ player), face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
    t += 1;
    printf("  %s de %s\n", face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
    t += 1;
  }

  // flop
  printf("\nFlop\n\
  %s de %s\n", face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
  t += 1;
  printf("  %s de %s\n", face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
  t += 1;
  printf("  %s de %s\n", face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
  t += 1;

  // turn
  printf("\nTurn\n\
  %s de %s\n", face[deck->V[t] % 13], naipe[deck->V[t] / 13]);
  t += 1;

  // river
  printf("\nRiver\n\
  %s de %s\n\n\n", face[deck->V[t] % 13], naipe[deck->V[t]/ 13]);
  t += 1;

  return 0;
};

 

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

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!