Randomly generate values from a repeatless vector in C

Asked

Viewed 35 times

0

I have the following scenario, which is a vector of questions that should be asked to the user randomly.

The problem is that after I enter the first input value the array is iterated right after listing all the values of the question vector. Inside the while loop I have one vector to store the answers and another to store the questions already asked, so I can then make a comparison with the array of questions so that no repeat questions are asked.

My doubt is about what is happening after I pass the input value, why does it loop after pressing Enter.

Below is the code:

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


int main()
{
  char perguntas[] = { 'a', 'b', 'c','d'};
  char respostas[4];
  char aux[4];

  int i =0;
  time_t t;
  srand((unsigned)time(&t));

  do{

      printf("%c\n", perguntas[rand()%4]);
      // scanf("%*c\n");
      scanf("%c\n",&respostas[i]);

      aux[i] = perguntas[rand()%4];

    }while( i < 4);

  return 0;
}
  • You draw a question index (printf("%c\n", perguntas[rand()%4]);) but reads an answer to index 0. Should not do do { int k = rand()%4; printf("%c\n", perguntas[k]); scanf("%c\n", &respostas[k]); i++; } while( i < 4);? You can initialize the answers array with a value, for example ' ', and test it before saving an answer, if it has already been filled in the question is repeated.

1 answer

1

There are several situations that are not right in this code:

  • Every time you do perguntas[rand()%4] generates a random number and therefore the number that generates and shows to the person is not the same that keeps to compare the ones that already left
  • The aux is not being used to understand if a question has already left
  • The i never incremented, so it is always with 0 turning an infinite loop

Note that this last point I mentioned answers directly to your question of it staying in loop.

Besides, the logic you have is not good. Better than drawing lots and seeing if you have already left is every time you draw, remove this element from the list, preventing it from coming out in the next draw. This ends up simplifying the code and avoiding situations where it generates mountains of elements until you can hit one that has not yet left.

Example of the logic I mentioned applied to your code:

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

void remover_pergunta(char perguntas[], int sorteada, int qtd){
    int i;
    for (i = sorteada + 1; i < qtd; ++i){ //loop empurra a sorteada para o fim do array
        int temp = perguntas[i];
        perguntas[i] = perguntas[i - 1];
        perguntas[i -1 ] = temp;
    }
}

int main(){
    char perguntas[] = { 'a', 'b', 'c','d'};
    char qtd_perguntas = sizeof(perguntas) / sizeof(char);
    char respostas[qtd_perguntas];
    int i = 0;
    srand (time(NULL));

    do{
        int pergunta_sorteada = rand() % qtd_perguntas; //sorteia pela posicao
        printf("%c\n", perguntas[pergunta_sorteada]); //mostra sorteada
        remover_pergunta(perguntas, pergunta_sorteada, qtd_perguntas); //"remove" sorteada
        qtd_perguntas--; //ajusta tamanho do array de perguntas
        scanf("%c\n",&respostas[i++]); //o incremento do i que estava em falta
    } while(qtd_perguntas > 0);

    return 0;
}

See the example in Ideone

The detail to point out in the code is that removing it from the question does not actually remove the question at the physical level, that is to say it puts the draw at the end, and decreases one unit in the size we are considering. It means that in practical terms it is as if the array has one less position, although the element is still there.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.