2013-11-23 27 views
1

我正在試圖找到一個隨機數字,其中有1到max數字(max < 10)。找到一個隨機數字長度1到10,使用數字0到9而不重複

srand((int) time(NULL)); 

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

BUT:

0,... 9只允許使用一次。

我發現,等待rand()創造這樣一些偶然的時間太長,所以我假設必須有創建運行總計其中每一個數字加一個比較時間由路。

+0

爲什麼不只是隨機生成每個十個位數? – Dmitri

+0

但是我如何確保排除前幾位數字,如彩票中的數字。 – Simona

+0

你說「最大數字」,但在你的示例代碼中,你暗示答案必須是從1到最大。這是什麼?所有的數字都可以在0到9的範圍內?你想要你的結果作爲一個字符串或'unsigned'或別的東西嗎? – Gene

回答

1

您可以逐個生成每個數字。首先,獲得一個從09的隨機整數。舉例來說,如果你得到5,然後從所有的數字數組中刪除:

0 1 2 3 4 6 7 8 9 

下得到一個隨機整數08,如果你得到8這一次,那麼第二個數字是9。刪除它並重復獲取下一個數字。

如果你需要獲得8位數字,例如,你到底有隻有4位離開,例如:

3 4 6 9 

然後得到03一個隨機整數。例如,如果您得到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; 
} 

希望這有助於。

編輯: 該函數的工作方式,它返回一個字符串的大小len,只使用數字1-9,沒有重複。

調用randstr(5)可以返回類似

12345 
93751 
73485 
... 

待辦事項,如果沒有更多的數字使用,該功能將只是坐在那裏循環。 評論在第一個功能

獲取隨機數字的數字其實很簡單。我們只是希望通過

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

1和10完成之間的隨機數可以使用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」中出現了第一位,轉向變得比它需要較少的數目。但是你可以通過修改'shuffle'在第一個位置添加避免'0'(例如,檢查第一個是否爲0,然後生成隨機pos = rand()%9 + 1,然後swap(a [0],a [ POS])或得到的數字,如果你需要它。

+1

你的洗牌不統一。查看「Fisher-Yates shuffle」上的維基百科頁面。 –

+0

我同意 - 改善洗牌功能。感謝您的鏈接 – VladimirM

3

如果您正在尋找n數字從0吸引到9,沒有重複(你的問題是很難解釋),那麼以下就足夠了一個整數。

的想法是把所有的數字從0到9的一頂帽子,然後畫出來一個接一個。每個附加到你正在構建的隨機整數值。

這頂帽子是一個數組初始設置0到9.

要在帽子中有k個元素時繪製數字,請計算[0..k-1]範圍內的隨機索引j,並從該數組中獲取該元素。然後將最後一個(k-1 th)元素向下複製到位置j,「刪除」它。剩餘的未使用數字現在在[0..k-2]中,您可以重複此過程直到完成。

追加一個數字d爲整數值是相同的話說

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

我剛剛在我的答案中寫了幾乎相同的代碼。我upvoted,但你需要小心不要以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; 
}