Non-repeating random number generator

后端 未结 7 1776
清酒与你
清酒与你 2020-12-21 00:57

I\'d like to make a number generator that does not repeat the number it has given out already (C++).

All I know is:

int randomgenerator(){
  int ran         


        
相关标签:
7条回答
  • 2020-12-21 01:07

    You are trying to solve the problem "the wrong way".

    Try this instead (supposing you have a vector<int> with question ids, but the same idea will work with whatever you have):

    1. Get a random R from 0 to N-1 where N is the number of questions in the container
    2. Add question R to another collection of "selected" questions
    3. If the "selected questions" collection has enough items, you 're done
    4. Remove question R from your original container (now N has decreased by 1)
    5. Go to 1
    0 讨论(0)
  • 2020-12-21 01:08

    What I would do:

    • Generate a vector of length N and fill it with values 1,2,...N.
    • Use std::random_shuffle.
    • If you have say 30 elements and only want 10, use the first 10 out the vector.

    EDIT: I have no idea how the questions are being stored, so.. :)

    I am assuming the questions are being stored in a vector or somesuch with random access. Now I have generated 10 random numbers which don't repeat: 7, 4, 12, 17, 1, 13, 9, 2, 3, 10.

    I would use those as indices for the vector of questions:

    std::vector<std::string> questions;
    //fill with questions
    for(int i = 0; i < number_of_questions; i++)
    {
        send_question_and_get_answer(questions[i]);
    }
    
    0 讨论(0)
  • 2020-12-21 01:19

    Should look more like this: (Note: does not solve your original problem).

    int randomgenerator(){
      int random;
    
      // I know this looks re-dunand compared to %11
      // But the bottom bits of rand() are less random than the top
      // bits do you get a better distribution like this.
    
      random = rand() / (RAND_MAX / 11);
    
      return random;
    }
    
    int main()
    {
        // srand() goes here.
        srand(time(0));
    
        while(true)
        {
            std::cout << randomgenerator() << "\n";
        }
    }
    

    A better way to solve the original problem is to pre-generate the numbers so you know that each number will appear only once. Then shuffle the order randomly.

    int main()
    {
        int data[] =  { 0,1,2,3,4,5,6,7,8,9,10,11};
        int size   =  sizeof(data)/sizeof(data[0]);
    
        std::random_shuffle(data, data + size);
    
        for(int loop = 0; loop < size; ++loop)
        {
            std::cout << data[loop] << "\n";
        }
    }
    
    0 讨论(0)
  • 2020-12-21 01:25

    Sounds like you essentially want to shuffle a deck of cards (in this case, the "cards" being the questions, or question numbers).

    In C++, I would do:

    #include <vector>
    #include <algorithms>
    
    std::vector<int> question_numbers;
    for (unsigned int i = 0; i < 10; ++i)
        question_numbers.push_back(i+1);
    std::random_shuffle(question_numbers.begin(), question_numbers.end());
    
    // now dole out the questions based on the shuffled numbers
    

    You do not have to hand out all of the questions, any more than you have to deal out a whole deck of cards every time you play a game. You can, of course, but there's no such requirement.

    0 讨论(0)
  • 2020-12-21 01:26

    Create a vector of 10 elements (numbers 1-10), then shuffle it, with std::random_shuffle. Then just iterate through it.

    0 讨论(0)
  • 2020-12-21 01:29

    Why not use some STL to perform the checks for you? The idea:

    Create an (initially empty) set of 10 integers that will be the indices of the random questions (they will be distinct as a set forbids duplicate items). Keep pushing random numbers in [0, num_of_questions-1] in there until it grows to a size of 10 (duplicates will get rejected automatically). When you have that set ready, iterate over it and output the questions of the corresponding indexes:

    std::vector<std::string> questions = /* I am assuming questions are stored in here */
    std::set<int> random_indexes;
    
    /* loop here until you get 10 distinct integers */
    while (random_indexes.size() < 10) random_indexes.insert(rand() % questions.size());
    
    for (auto index: random_indexes){
        std::cout << questions[index] <<std::endl;
    }
    

    I may be missing something, but it seems to me the answers that use shuffling of either questions or indexes perform more computations or use an unnecessary memory overhead.

    0 讨论(0)
提交回复
热议问题