成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

比較洗牌算法的兩種實現方法

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

方法一:隨機生成法

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

實現代碼如下:

  1. size_t shuffle(char s[], int n) 
  2.     size_t t=0;//計算循環次數 
  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函數(時間復雜度可能是O(n),沒找到依據),即使是O(1),它的循環生成隨機數的次數是不固定的(大于等于需要生成的個數)。

方法二:交換位置法

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

實現代碼:

  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;//計算循環次數 
  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; 

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

測試代碼:

 

結果:

image

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

后續補充:

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

  1. size_t shuffle22(int s[], int n) 
  2.     size_t t=0;//計算循環次數 
  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個數還在第1個位置的概率是1/n,后續移動只會減少這個概率。所以這個算法不是完全隨機的"。修改后的算法其實就是使用C++的STL<algorithm>庫中的random_shuffle()函數的實現方法。取隨機數的時候的范圍每次都隨著i的改變而變動,這樣就不會減少之前的位置的數還是原來的數的概率了(即后續交換操作不會影響到已經交換過的位置)。

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

  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多表聯查

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比較

2010-04-25 17:34:30

負載均衡實現

2013-06-27 09:26:50

Android界面刷新

2022-02-09 07:03:01

SpringNacos服務注冊

2010-09-13 13:05:03

sql server分

2020-09-23 09:24:01

堆棧開發實現

2010-09-06 17:26:54

SQL函數

2009-06-19 17:05:08

MVC框架Struts和Spri

2011-06-23 09:07:16

2021-12-08 10:47:35

RabbitMQ 實現延遲

2022-02-21 08:18:38

option編程模式

2010-07-14 10:30:26

Perl多線程

2009-10-20 13:59:59

網絡綜合布線系統

2017-11-16 09:20:20

內存虛擬化技術

2010-09-17 09:37:27

Java安裝方法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产欧美一区二区三区久久人妖 | www.精品国产 | 第一区在线观看免费国语入口 | 亚洲第一黄色网 | 天天看天天干 | av网站推荐 | 在线中文字幕视频 | 久久久.com | 成人av播放 | 麻豆精品国产91久久久久久 | 日韩av一二三区 | 男女视频在线观看网站 | www在线视频 | 免费人成在线观看网站 | 在线不卡视频 | a视频在线播放 | 美女操网站 | 一级片成人 | 蜜桃av人人夜夜澡人人爽 | 97精品一区二区 | 天天操天天干天天爽 | 国产成人精品999在线观看 | 99精品欧美一区二区蜜桃免费 | 国产视频三级 | 自拍偷拍第一页 | 免费在线观看av | 在线免费观看黄色 | 欧美性生活视频 | 欧美成人精品二区三区99精品 | 瑟瑟激情 | 久久高清 | 一区二区三区av夏目彩春 | 成人激情视频免费在线观看 | 超碰超碰| 国产一区二区在线免费播放 | 天天色综网 | 国产精品69久久久久水密桃 | 伊人超碰| 网站国产 | 日韩av在线免费 | 成人免费淫片aa视频免费 |