2011-03-21 2 views
5

Я хотел бы сделать генератор чисел, который не повторяет номер, который он выдал уже (C++).Генератор случайных чисел, не повторяющийся

Все, что я знаю:

int randomgenerator(){ 
    int random; 
    srand(time(0)); 
    random = rand()%11; 
    return(random); 
} // Added this on edition 

Эта функция дает мне лишние цифры.

Я пытаюсь создать программу анкеты, которая выдает 10 вопросов в случайном порядке, и я не хочу, чтобы какие-либо вопросы появлялись снова.

Кто-нибудь знает синтаксис?

+1

Если ваш генератор случайных чисел не может повториться, он теряет важный аспект случайности. Если кто-то знает период, их точность догадок возрастает по мере приближения к концу периода, со 100% -ной уверенностью в последнем предположении. – corsiKa

+5

srand() должен запускаться ** ONCE ** и только один раз при запуске программы. –

+0

Вы можете просто сохранить как int последнее значение, а если новое значение равно последнему, добавьте случайное число от 1 до максимального значения, которое вы хотите, за вычетом полученного вами номера. Вы можете сделать это просто с помощью модуля, и это скорее более случайный-y, чем просто использование rand() :) –

ответ

18

Что бы я сделал:

  • Сформировать вектор длины N и заполнить его значениями 1,2, ... N.
  • Использование std::random_shuffle.
  • Если вы сказали 30 элементов и хотите только 10, используйте первые 10 из вектора.

EDIT: Я понятия не имею, как хранятся вопросы, так .. :)

Я предполагаю, что вопросы хранятся в векторе или сконвертировано с произвольным доступом. Теперь я создал 10 случайных чисел, которые не повторяются: 7, 4, 12, 17, 1, 13, 9, 2, 3, 10.

Я хотел бы использовать их в качестве индексов для вектора вопросов:

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

+1 Потому что быстрее, чем Джон! – ybungalobill

+5

+1 Потому что быстрее, чем у меня! :) – Jon

+0

Мне это нравится, но я до сих пор не знаю, как это поможет мне подобрать вопросы. –

7

Вы пытаетесь решить проблему «неправильным способом».

Попробуйте вместо (предположим, у вас есть vector<int> с вопросительными идентификаторами, но та же идея будет работать с тем, что у вас есть):

  1. Получить случайное R от 0 до N-1, где N это число вопросы в контейнере
  2. Добавить вопрос R в другую коллекцию «отобранные» вопросы
  3. Если «отдельные вопросы» коллекции есть достаточное количество элементов, вы закончите
  4. Удалить вопрос R из исходного контейнера (теперь N уменьшилось на 1)
  5. Перейти к 1
+0

привет, не могли бы вы помочь мне создать настоящую функцию? Я новичок в C++, и я понятия не имею, какой именно вектор. D: –

+0

@Jpeh: Как хранятся ваши вопросы? Кроме того, это домашнее задание? – Jon

+0

Я использую функцию, которую я написал в вопросе, чтобы выбрать случайное число между 0-10, и я возвращаю значение в свою основную программу. Независимо от того, что это значение эквивалентно определенному вопросу (например, если random == 1, тогда я вызову функцию: «вопрос 1». Нет, это не домашнее задание. Я просто программирую энту здесь: D –

6

Похоже, вы по существу хотите shuffle a deck of cards (в данном случае, «карты», находящиеся на вопросы, или номер вопроса).

В C++, я хотел бы сделать:

#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 

Вы не должны раздать все вопросы, больше, чем вы должны заниматься целую колоду карт каждый раз, когда вы играете в игру. Вы можете, конечно, но такого требования нет.

4

Создайте вектор из 10 элементов (цифры 1-10), затем перетасуйте его, используя std::random_shuffle. Затем просто пройдите через него.

+0

@Benjamin: Я думаю, что OP хочет случайно выбрать N из M. – Jon

+2

@Jon : Да, вы только перебираете N элементов. –

+0

@Jon: это по сути то же самое, но этот подход дает вам время O (N + M), пока вы даете O (NM). – ybungalobill

1

должен выглядеть примерно так: (Примечание: не поможет решить исходную задачу).

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"; 
    } 
} 

Лучший способ для решения исходной задачи является предварительно генерировать числа так, вы знаете, что каждый номер будет отображаться только один раз. Затем произвольно перемешайте порядок.

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"; 
    } 
} 
Смежные вопросы