程式模擬洗撲克牌(演算法)

2021-06-22 15:25:17 字數 1439 閱讀 7813

前提:一副撲克牌有54張,因此我們可以乙個整型陣列array[54]或者map來儲存,"a"用0~3,"2"用4~7,"3"用8~11......"k"用48~51,小鬼用52,大鬼用53表示。關於花色,我們可以這樣表示:4i表示紅桃,4i+1表示黑桃,4i+2表示梅花,4i+3表示方塊(0<=i<=12)。這樣的話,就退化成乙個陣列問題,而不關心其表示形式,從而達到邏輯與表現形式脫離。

解法1:

隨機產生0~53的亂數並將之存入陣列中,後來產生的亂數存入陣列前必須先檢查陣列中是否已有重複的數字,如果有這個數字就不存入,在重新產生下乙個數。

//使用hashmap,目的是為了加快查詢速度,hashmap中的key即為撲克牌序列

//產生隨機數,若該隨機數在hashmap有,則一直生成隨機數,直到沒有為止

public int create_1(){

hashmaphashmap=new hashmap();

int array =new int [54];

random rand;

int num;

for(int i=0;i分析:隨著產生的隨機數的數目的增加,能夠正確生成下乙個隨機數的概率在下降,比如說能正確生成第乙個數的概率是54/54,能正確生成第二個數的概率降為53/54,能正確生成第i個數的概率變為(55-i)/54,能正確生成最後乙個數的概率是1/54,這樣的話就需要遠不止54次了。

解法2:將陣列先依序由0到53填入,然後使用乙個迴圈走訪陣列,並隨機產生0~53的亂數,將產生的亂數當作索引取出陣列值,並與目前陣列走訪到的值相交換。

//依靠交換陣列中的兩個值

public int create_2(){

int array=new int [cardnum];

random rand;

int num;

for(int i=0;i分析:演算法2的確比演算法1快很多,而且看起來像是正確的,其實生成的某個序列在所有序列中並不是等可能的。最終可能的序列有n!種,而在交換的過程中,有n^n種,這樣當n>2時,

n^n/(n!)並不為乙個整數,因此生成序列的概率並不相等。

演算法3:在演算法2的基礎上改進,我們只交換當前需要交換的和後面沒有交換的。

//依靠交換陣列中的兩個值

// 只交換i和i後面的

public int create_3(){

int array=new int [cardnum];

random rand;

int num;

for(int i=0;i分析:該演算法是正確,而且效率比較高,實際上我們可以使用庫函式,從而達到更高的效率。

演算法4:使用庫函式,效率更高。

public int create_4(){

int array=new int [cardnum];

for(int i=0;i總結:以上的四種想法是一步步的改進與提煉,隨著時間的增長,人才會慢慢成長吧。

洗撲克牌(亂數排列)

洗撲克牌。亂數排列 說明 洗撲克牌的原理其實與亂數排列是相同的,都是將一組數字 例如1 n 打亂重新排列,只不過洗撲克牌多了乙個花色判斷的動作 而已。解法 初學者通常會直接想到,隨機產生1 n的亂數並將之存入陣列中,後來產生的亂數存入陣列前必須先檢查陣列中是否已有重複的數 字,如果有這個數就不存入,...

洗撲克牌 亂數排序

洗撲克牌 亂數排列 說明 洗撲克牌的原理其實與亂數排列是相同的,都是將一組數字 例如1 n 打亂重新排列,只 不過洗撲克牌多了乙個花色判斷的動作而已。解法 初學者通常會直接想到,隨機產生1 n的亂數並將之存入陣列中,後來產生的亂數存入陣列 前必須先檢查陣列中是否已有重複的數字,如果有這個數就不存入,...

洗撲克牌(亂數排列)

說明 洗撲克牌的原理其實與亂數排列是相同的,都是將一組數字 例如1 n 打亂重新排列,只不過洗撲克牌多了乙個花色判斷的動作而已。解法 初學者通常會直接想到,隨機產生1 n的亂數並將之存入陣列中,後來產生的亂數存入陣列前必須先檢查陣列中是否已有重複的數字,如果有這個數就不存入,再重新產生下乙個數,運氣...