自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

比較洗牌算法的兩種實現(xiàn)方法

開發(fā) 后端 算法
我們首先會介紹隨機生成法,該方法要點就是從頭開始逐個隨機生成規(guī)定區(qū)域的數(shù)字,如果新生成隨機數(shù)之前已經(jīng)生成過就不保存該數(shù);如果新生成的隨機數(shù)之前沒有生成過就保存該數(shù);直到生成的數(shù)字的數(shù)量達到所需的數(shù)量。接下來我們還會介紹交換位置法。

方法一:隨機生成法

首先,我介紹一種很常見的方法:隨機生成法(我自己命名的),這方法我在掃雷游戲中隨機分布雷的位置時用過(思想是一樣的),該方法要點就是從頭開始逐個隨機生成規(guī)定區(qū)域的數(shù)字,如果新生成隨機數(shù)之前已經(jīng)生成過就不保存該數(shù);如果新生成的隨機數(shù)之前沒有生成過就保存該數(shù);直到生成的數(shù)字的數(shù)量達到所需的數(shù)量。

實現(xiàn)代碼如下:

  1. size_t shuffle(char s[], int n) 
  2.     size_t t=0;//計算循環(huán)次數(shù) 
  3.     int c=0; 
  4.     while(c<n) 
  5.     { 
  6.         t++; 
  7.         int num = rand()%n; 
  8.         if (memchr(s,num,c) == NULL) 
  9.         { 
  10.             s[c++] = static_cast<char>(num); 
  11.         } 
  12.     } 
  13.     return t; 
  14.  
  15.  
  16. void printCards(char s[], int n) 
  17.     for (int i=0; i<n; i++) 
  18.     { 
  19.         cout << static_cast<int>(s[i]) << " "
  20.     } 
  21.     cout << endl; 

代碼中使用了memchr函數(shù)(時間復雜度可能是O(n),沒找到依據(jù)),即使是O(1),它的循環(huán)生成隨機數(shù)的次數(shù)是不固定的(大于等于需要生成的個數(shù))。

方法二:交換位置法

這種方法是我昨天在參加騰訊筆試考試時候想到的,今天回到學校后在寢室測試了一番,基本思路是:先初始化一串分布的數(shù)字,然后為每個位置依次生成一個與之交換的隨機位置,如果生成的隨機位置不是它本身就執(zhí)行交換操作。

實現(xiàn)代碼:

  1. void swap(int& a, int& b) 
  2.     a = a^b; 
  3.     b = a^b; 
  4.     a = a^b; 
  5.  
  6. size_t shuffle2(int s[], int n) 
  7.     size_t t=0;//計算循環(huán)次數(shù) 
  8.     for (int i=0; i<n; i++) 
  9.     { 
  10.         t++; 
  11.         s[i] = i; 
  12.     } 
  13.     for (int i=0; i<n; i++) 
  14.     { 
  15.         t++; 
  16.         int num = rand()%n; 
  17.         if (num != i) 
  18.         { 
  19.             swap(s[num],s[i]); 
  20.         } 
  21.     } 
  22.     return t; 
  23.  
  24. void printCards2(int s[], int n) 
  25.     for (int i=0; i<n; i++) 
  26.     { 
  27.         cout << s[i] << " "
  28.     } 
  29.     cout << endl; 

比較:在時間上方法二比方法一快好多,因為交換位置的次數(shù)的***值是限定了的(生成隨機數(shù)的次數(shù)是固定的),而且省去了查找新生成數(shù)是否在已生成數(shù)中的時間。方法一中,當新生成的數(shù)在已生成的數(shù)中就需要從新生成一個隨機數(shù),從而隨機生成數(shù)的次數(shù)是不固定的(有最小值)。

測試代碼:

 

結果:

image

我還是不能確定第二種方法是不是更好的,因為是自己想到的,我的驗證也不是很完善,也許有什么其他的缺點(比如說隨機性太弱),也沒在其他書上看到過,如果網(wǎng)友們在哪看到過就告訴下我吧,方法一是在《c和c++代碼精粹》中文版P97中找到的。

后續(xù)補充:

謝謝chncwang的回復,方法二不是完全隨機的,完全隨機的修改如下:

  1. size_t shuffle22(int s[], int n) 
  2.     size_t t=0;//計算循環(huán)次數(shù) 
  3.     for (int i=0; i<n; i++) 
  4.     { 
  5.         t++; 
  6.         s[i] = i; 
  7.     } 
  8.     for (int i=n-1; i>0; --i) 
  9.     { 
  10.         t++; 
  11.         int num = rand()%(i+1); 
  12.         if (num != i) 
  13.         { 
  14.             swap(s[num],s[i]); 
  15.         } 
  16.     } 
  17.     return t; 
因為"第1次移動后,第1個數(shù)還在第1個位置的概率是1/n,后續(xù)移動只會減少這個概率。所以這個算法不是完全隨機的"。修改后的算法其實就是使用C++的STL<algorithm>庫中的random_shuffle()函數(shù)的實現(xiàn)方法。取隨機數(shù)的時候的范圍每次都隨著i的改變而變動,這樣就不會減少之前的位置的數(shù)還是原來的數(shù)的概率了(即后續(xù)交換操作不會影響到已經(jīng)交換過的位置)。

使用標準庫<algorithm>中的random_shuffle()函數(shù)實現(xiàn)很簡單,代碼如下:

  1. int main() 
  2.     vector<int> s_stl; 
  3.     for (int i=0; i<CARDS_COUNT; ++i) s_stl.push_back(i); 
  4.     random_shuffle(s_stl.begin(),s_stl.end()); 
  5.     cout << "使用C++算法庫:"
  6.     for (vector<int>::iterator it=s_stl.begin(); it!=s_stl.end(); ++it) 
  7.         cout << " " << *it; 
  8.     return 0; 

 

原文鏈接:http://www.cnblogs.com/hanxi/archive/2012/10/15/2725047.html

【編輯推薦】

 

 

 

責任編輯:彭凡 來源: 博客園
相關推薦

2010-10-14 14:33:15

MySQL多表聯(lián)查

2010-07-13 10:47:18

Perl面向對象

2010-07-14 16:28:58

配線架

2011-08-09 13:50:01

iPhone動畫UIView

2009-07-31 14:04:11

C#時間比較大小

2009-04-21 11:23:56

Oraclespool比較

2013-06-27 09:26:50

Android界面刷新

2022-02-09 07:03:01

SpringNacos服務注冊

2010-04-25 17:34:30

負載均衡實現(xiàn)

2010-09-13 13:05:03

sql server分

2020-09-23 09:24:01

堆棧開發(fā)實現(xiàn)

2010-09-06 17:26:54

SQL函數(shù)

2009-06-19 17:05:08

MVC框架Struts和Spri

2011-06-23 09:07:16

2009-10-20 13:59:59

網(wǎng)絡綜合布線系統(tǒng)

2017-11-16 09:20:20

內存虛擬化技術

2010-09-17 09:37:27

Java安裝方法

2022-02-21 08:18:38

option編程模式

2010-07-14 10:30:26

Perl多線程

2021-12-08 10:47:35

RabbitMQ 實現(xiàn)延遲
點贊
收藏

51CTO技術棧公眾號