2012-07-18 54 views
2

只需編寫一個程序來洗牌一副撲克牌,並獲得取決於RNG是否內部或外部的for循環播種不同的行爲; 即。for循環內奇怪的srand行爲; C++

for(int i = 0; i < 52; i++) 
{ 
    srand(time(0)); 
    Card temp = deck[i]; 
    int toSwap = rand()%52; 
    deck[i] = deck[toSwap]; 
    deck[toSwap] = temp; 
} 

使輸出

Nine of Hearts 
Ace of Clubs 
Two of Clubs 
Three of Clubs 
Four of Clubs 

等,但

void DeckOfCards::shuffle() 
{ 
    srand(time(0)); 
    for(int i = 0; i < 52; i++) 
    { 
    Card temp = deck[i]; 
    int toSwap = rand()%52; 
    deck[i] = deck[toSwap]; 
    deck[toSwap] = temp; 
    } 
    currentCard =0; 
} 

導致

Ace of Hearts 
Queen of Spades 
Four of Hearts 
Seven of Clubs 
Five of Hearts 

(正確的功能)。任何人都知道爲什麼重新加入RNG會導致這種情況?只需要,如果你需要的僞隨機量一旦

+0

如果是隨機得到的時候,你怎麼知道的第一個輸出是不正確的? – jrad 2012-07-18 15:03:30

+0

時間(0)給出不同的結果 - 你期望什麼? – 2012-07-18 15:04:01

+0

這裏沒有奇怪的行爲。沿着移動.. :) – ltjax 2012-07-18 15:04:37

回答

3

由於時間(NULL)每秒只改變一次,如果for循環不超過一秒完成。

2

種子。如果您多次調用srand,並且如果您在時鐘種子更改之前執行該操作,則會得到相同的值而不是隨機值。剛開始就種一次。你可以打開其他程序(winamp等)來獲得更多的隨機值(你需要減慢你的程序;)或者爲隨機迭代創建空循環可以修復第一個程序。但你需要非常大的隨機數,如20億(必須小於40億))

0

當其他人是完全正確的,你不希望使用函數srand(時間(0))在循環中,因爲你會得到隨機性較差,因爲你重複設置相同的種子,你不妨請牢記以便進行調試:如果您需要能夠「重放」某個案例,請將種子寫入日誌文件並允許顯式設置種子。否則,用隨機數字應用程序的調試可以是相當棘手......

0

可以使用升壓POSIX時間來代替。

,但在任何情況下,如果你需要調用函數srand只有兩次,就可以使用兩個不同的固定值。

或者我用這個功能毫秒的

inline long 
    getTimeMs() 
    { 
     struct timeval start; 
     long mtime; 

     gettimeofday (&start, NULL); 

     mtime = ((start.tv_sec) * 1000 + start.tv_usec/1000.0) + 0.5; 

     return mtime; 
    } 

問候