2013-11-23 2 views
1

Я пытаюсь найти случайное число, которое имеет от 1 до max цифр (max < 10).Найти случайное число от 1 до 10, используя числа от 0 до 9 без повторений

srand((int) time(NULL)); 

answer = ((rand() % max) + 1); 

НО:

0 ... 9 разрешено только быть использован только один раз.

Я обнаружил, что ждет rand() создать такое количество случайно занимает слишком много времени, поэтому я предполагаю, что там должен быть способ, чтобы создать нарастающим итогом, где каждый раз, когда цифра добавляется сравнение производится ,

+0

Почему не просто случайным образом каждый из десяти цифр? – Dmitri

+0

Но как я могу исключить предыдущие цифры, например, в лотерею. – Simona

+0

Вы сказали «максимальные цифры», но в вашем примере кода вы подразумеваете, что ответ должен быть от 1 до макс. Что он? Может ли _all_ цифры находиться в диапазоне от 0 до 9? Вы хотите, чтобы ваш результат был как строка или 'unsigned' или что-то еще? – Gene

ответ

1

Вы можете генерировать каждую цифру по одному. Сначала получите случайное целое число от 0 до 9. Например, если вы получаете 5, а затем удалить его из массива всех цифр:

0 1 2 3 4 6 7 8 9 

Следующая получить случайное число от 0 до 8, если вы 8 на этот раз, то вторая цифра 9. Удалите его и повторите следующую цифру.

Если вам необходимо получить 8 цифр, например, в конце концов у вас есть только 4 цифры слева, например:

3 4 6 9 

Тогда получить случайное число от 0 до 3. Если, например, вы получаете 0, то последняя цифра 3, а остальная часть отбрасывается.

+0

1. Это не дает объяснения для того, чтобы сделать число случайным размером (числом цифр). и 2. Этот метод позволил бы создать такое число, как '0453', которое, вероятно, не должно быть разрешено (начало нуля). – nhgrif

+1

Лидирующий ноль будет легальным. Объяснение велико, однако я изо всех сил пытаюсь это кодировать. – Simona

+0

@nhgrif Я использую 8 цифр только в качестве примера, его легко изменить на случайное число 'max'. –

0

Вы можете настроить функцию:

char * randstr(int len) 
{ 
    srand(0); //seed the generator 
    char * str = malloc(len); //allocate exactly len bytes 
    int i, x; //define some loop variables 
    char used = 0; //used is to check if the number has already been taken 
    char num; //a temp value 
    for (i = 0; i < len; i++) 
    { //this loop runs through each character in the string 
      used = 1; 
      while (used) //basically, if we already used it, find another 
      { 
       used = 0; 
       num = rand() % 10 + 48; //48 = '8' //returns 0-9 
       for (x = 0; x < i; x++) 
       { //this loop checks to see if its already been used 
        if (str[x] == num) used = 1; 
       } 
      } 
    } 
    return str; 
} 

Это возвращает массив символов, но не оканчивающийся нуль один, хотя все номера будет в виде ASCII. Для строки с нулевым завершением просто измените ее так:

char * randstr(int len) 
{ 
    srand(0); 
    char * str = malloc(len + 1); 
    int i, x; 
    char used = 0; 
    char num; 
    for (i = 0; i < len; i++) 
    { 
      used = 1; 
      while (used) 
      { 
       used = 0; 
       num = rand() % 10 + 48; //48 = '8' 
       for (x = 0; x < i; x++) 
       { 
        if (str[x] == num) used = 1; 
       } 
      } 
    } 
    str[len - 1] = 0; 
    return str; 
} 

Надеюсь, это поможет.

EDIT: Как работает функция, она возвращает строку размера len, используя только цифры 1-9, без повторов.

вызова randstr (5) может вернуть что-то вроде

12345 
93751 
73485 
... 

делать заметки, если нет больше чисел для использования, функция будет просто сидеть там зацикливание. Комментарии находятся в первой функции

Получение случайного числа цифр будет на самом деле довольно простым. Мы просто хотим, случайное число между 1 и 10. Совершено на

rand() % 10 + 1; 


//so lets assign that to an int and call our function 
int num = rand() % 10 + 1; 
char * str = randstr(num); //assume this is the null terminated one 
printf("The number was %s\n", str); 
+0

1. Это не дает объяснения для того, чтобы сделать число случайным размером (количество цифр). и 2. Этот метод позволил бы создать такое число, как 0453, которое, вероятно, не должно быть разрешено (начало нуля). – nhgrif

+0

nhgrif отредактирован .. – phyrrus9

+0

Вопрос задан для чисел между 0-9. Ваше решение предоставляет только номера от 1 до 9. И вы по-прежнему не объясняете, как получить случайное число цифр (хотя я знаю, как объяснение не дано в ответе). – nhgrif

0

Вы можете использовать массив из 10 цифр, перетасовать их каждый раз и получить N первых цифр.Псевдо код:

void shuffle(char[] a) { 
    for(int i=0; i< 10; i++) { 
     pos = rand() % 10; 
     swap(a[i], a[pos]); 
    } 
} 
int main() { 
    char arr[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 

    # it prints endlessly random numbers of random length 
    while (1) { 
     shuffle(arr); 
     int N = rand() % 10 + 1; # how many digits to generate 
     for (int i=0; i<N; i++) { 
      printf(arr[i]); 
     } 
    } 
    printf("\n"); 
} 

Возможный вопрос таким образом, когда «0» приходит первую цифру, переворачивая номер, получает меньшее количество, чем это требуется. Но вы можете добавить избегать «0» в первой позиции, установив «перетасовку» (например, проверьте, является ли первый «0», а затем генерирует случайный pos = rand()% 9 + 1, а затем свопинг (a [0], a [ поз]) или получить номера, если вам это нужно.

+1

Ваша тасовка не является однородной. Проверьте страницу википедии на «Shuffle Fisher-Yates». –

+0

Я согласен - функция shuffle должна быть улучшена. Спасибо за ссылку – VladimirM

3

Если вы ищете целое с n цифрами нарисованного от 0 до 9, без повторов (ваш вопрос трудно интерпретировать), то следующий будет достаточно.

Идея состоит в том, чтобы поместить все цифры от 0 до 9 в шляпе, а затем вывести их один за другим. Приложите все к произвольному целочисленному значению, которое вы строите.

Шляпа - это массив, изначально заданный 0 до 9.

Чтобы нарисовать номер, когда в шляпе есть k элементов в нем, вычислите случайный индекс j в диапазоне [0..k-1] и получите этот элемент из массива. Затем скопируйте последний (k-1-й) элемент до позиции j, который «стирает» его. Остальные незаблокированные цифры теперь находятся в [0..k-2], и вы можете повторить этот процесс до завершения.

присоединяя значного цифро целое значение такое же, как говорят

val = 10 * val + d 

Подставив эти идеи вместе, вы следующие. Обратите внимание, что это позволяет 0 в первой позиции, поэтому на самом деле результат может иметь не более n цифр при печати без начальных нулей.

unsigned random_unrepeated_digits(int n) { 
    int i, digits[] = { 0,1,2,3,4,5,6,7,8,9 }; 
    unsigned val = 0; 
    for (i = 0; i < n; i++) { 
    int k = 10 - i, j = rand() % k; 
    val = 10 * val + digits[j]; 
    digits[j] = digits[k - 1]; 
    } 
    return val; 
} 
+0

Я просто написал почти такой же код в своем ответе. Я поддерживал, но вам нужно быть осторожным, чтобы не начинать результат с 0, а когда n равно 10, ваш unsigned может переполняться. –

+0

@ Анонимное спасибо. Я знаю это. На самом деле я сказал, что он позволяет 0, в первую очередь, что он не исключил. Его вопрос нечеткий. Если он действительно исключит эти вещи, я их исправлю. – Gene

1

Вы можете тасовать цифры {0, 1, 2, ..., 9}, стараясь не ставить 0, а затем построить число из соответствующего числа начальных цифр. Делая это, при построении результата, как вы идете, и остановить перетасовки, как только вы зафиксировали первые ndig цифры, вы в конечном итоге с кодом, как это:

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

long long rand_digits(int ndig) { 
    int digits[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 
    long long res = 0; 
    for (int i = 0; i < ndig; i++) { 
     int r = i + rand() % (10 - i - (i == 0)); 
     res = res * 10 + digits[r]; 
     digits[r] = digits[i]; 
    } 
    return res; 
} 

int main(int argc, char *argv[]) { 
    srand((unsigned)time(0)); 
    for (int i = 0; i < 10; i++) { 
     printf("%-2d: %lld\n", i + 1, rand_digits(i + 1)); 
    } 
    return 0; 
} 
Смежные вопросы