0

Using C, How do I randomly display values within an array considering that each of these values has a unique corresponding value without repeating any of these values displayed? Using C, my goal is to randomly display questions, one at a time, for a set amount of iterations. I created an array that holds the questions and their four possible answers. I also created an array that holds the correct answer for each question.

Thank you very much... You guys have been really helpful

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h> 

int random();
int l, qs[10];
int main ()
{
for (l=0;l<10;++l)
qs[l]=0;
srand(time(NULL));
char questions [] [50]  ={"aa \n\na)\n\nb)\n\nc)\n\nd)",\"bb   \n\na)\n\nb)\n\nc)\n\nd)", "cc \n\na)\n\nb)\n\nc)\n\nd)", \
"dd \n\na)\n\nb)\n\nc)\n\nd)", "ee \n\na)\n\nb)\n\nc)\n\nd)", \
"ff \n\na)\n\nb)\n\nc)\n\nd)", "gg \n\na)\n\nb)\n\nc)\n\nd)", \
"hh \n\na)\n\nb)\n\nc)\n\nd)", "ii \n\na)\n\nb)\n\nc)\n\nd)", \
"jj \n\na)\n\nb)\n\nc)\n\nd)"};
char answers [10] = {'a','b', 'b','d','c','b','d','b' ,'c', 'b'};
int i, j;
char ans;
int score = 0;
printf ("Read each question carefully and choose your best answer.");
for (i=1;i<6;i++)
{
j = random();
fflush(stdin);
clrscr();
printf ("\n %d %s \n\n", i, questions [j]);
printf ("\n Enter Answer: ");
do
{
ans = tolower(getchar());
}while ( (ans < 'a') || (ans > 'd'));
printf ("\nYou chose: %c ", ans);
if (ans == answers[j])
{score = score + 1;
printf ("\n\nCorrect. %d Mark/s", score);
}else{printf ("\n\nIncorrect. 0 Mark/s");}
printf("\n\nPress Enter for next question...");
getch ();
}
getch ();
return 0;
}
random ()
{
int k;
do
{k=rand()%10;
}while (qs[k]!=0);
qs[k]= 1;
return k;
}

3 Answers3

1

First and foremost, I'd change how you're arranging the data. Right now, you have three parallel arrays, one for questions, one for potential answers, and one for correct answers.

Instead of that, I'd create a struct to hold all the data for a single question, something like this:

struct qa { 
    char question[64];
    char answers[4][32];
    int correct_answer;
};

Then I'd create an array of qa structs, each holding all the data for a single question and answer:

qa questions[] = {
    { "what color is the sky?", { "red", "green", "blue", "yellow"}, 2},
    { "When is Christmas?", {"January", "July", "September", "December"}, 3},
    // ...
};

From there, you have a couple of choices. If you're going to ask all (or nearly) all the questions and primarily want to shuffle the order, you can use a Fisher-Yates shuffle as @Salvatore Previti suggested.

If you're only asking a small percentage of the questions at any given time, that can be pretty wasteful. In such a case, you might use (for one example) a selection algorithm invented by Robert Floyd that I discussed in a previous answer.

Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

You need another list to keep track of what item you extracted.

A possible solution: shuffle the input array. See http://benpfaff.org/writings/clc/shuffle.html

If you cannot modify the input array, you can use indices instead, a level of indirection. This is another possible solution.

1) You create an integer array of size n.

2) You fill the array with values from 0 to n-1 (included).

3) You shuffle the array (look for a shuffle method to randomize an array), for example, again http://benpfaff.org/writings/clc/shuffle.html

4) You then iterate on the array from 0 to n-1 (included), each item in the array will be the index in the source array.

Done.

Another possible solution would be to use a linked list.

1) You fill the linked list in random order (this is quite easy).

In pseudocode, for example

for (int i = 0; i < n; ++i)
{
    if (rand() & 1)
        insert_at_the_beginning();
    else
        insert_at_the_end();
}

2) When you need a new item, you pop the first item from the linked list.

Done.

You can also keep an array of boolean values, but in this case the complexity of the algorithm will be higher, the first method seems enough.

Salvatore Previti
  • 8,956
  • 31
  • 37
0

Don't call srand in the for loop. Call it once at the beginning of your program and let it be. The cool way of doing what you want is the Fisher–Yates shuffle. You can look it up if you want to use it. if not, here is the trivial solution:

1) Before the loop, make an array of bools of size 10 (ill call it usedArray) and set all to false.

2) to get the question index, get a random number between 0 and 9, inclusive (j = rand%10; is good), such that usedArray[j] is false; then, set usedArray[j] to true. you may want to use a while or do-while loop for this.

2) Your question is now questions[j], and it's corresponding answer is answers[j]

3) repeat as necessary

aleph_null
  • 5,766
  • 2
  • 24
  • 39