Pergunta

Questions are stored like:

 arr[y][x] = { "Question1text" , "answer1" , "answer2" , "answer3" , .... , "boolean" }

get random Question

randomQuestion = qrand() % questionCount;

I set nr 6 to = "1" when i already used that question, so i now look for a random one but without "1" set

while( question[randomQuestion][6] == "1" )
{
    randomQuestion = qrand() % questionCount;
}

but let's say there's just 1 question out of 10k left. the chance of the random number to hit exactly that question ain't so bright. So there's gotta be a better way of achieving this, but how?

Foi útil?

Solução 2

Shuffle the questions, then simply iterate through the shuffled set. When you get to the end of the set, re-shuffle and start over. Shuffling n questions takes O(n) work, so as long as you're storing them in memory anyway this is a cheap and simple solution.

Outras dicas

Instead of using an old-school array you could store your questions (define a class or struct for a single question) in a list-class like QList. Then you can remove the questions after they are used...

try something like this:

randomQuestion = qrand() % questionList.count();
nextQuestion = questionList.takeAt(randomQuestion);

You can use standard class std::bitset that to mark questions that were already selected. Here is an example that you may use as a base

#include <iostream>
#include <bitset>
#include <cstdlib>
#include <ctime>

int main() 
{

    const size_t N = 10;
    char s[N][3] = { "Q0", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9" };
    std::bitset<N> b;

    std::srand( ( unsigned int )std::time( 0 ) );

    size_t availableQuestions = N;

    while ( availableQuestions )
    {
            size_t i = std::rand() % availableQuestions;
            size_t question = 0;
            while ( i != 0 || b[question] )
            {
                if ( !b[question++] && i != 0 ) --i;
            }

            b.set( question );
            std::cout << s[question] << std::endl;
            --availableQuestions;
    }

    return 0;
}

The output at the first run is

Q1
Q9
Q8
Q4
Q6
Q5
Q3
Q2
Q7
Q0

The output at the second run is

Q7
Q5
Q0
Q1
Q2
Q4
Q9
Q8
Q6
Q3

It would be even better to use a for loop instead of the while loop

for ( size_t availableQuestions = N; availableQuestions != 0; --availableQuestions )
{
    size_t i = std::rand() % availableQuestions;
    size_t question = 0;

    while ( i != 0 || b[question] )
    {
        if ( !b[question++] && i != 0 ) --i;
    }

    b.set( question );
    std::cout << s[question] << std::endl;
}

Enjoy!:)

How about something like that?

question[randomQuestion] = question[--questionCount];

do not use an array , use list instead so you can remove selected questions from it. then simply select a member of list randomly.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top