C語言經典算法 - 洗牌算法

wdey 9年前發布 | 2K 次閱讀 C/C++

說明:
洗撲克牌的原理其實與亂數排列是相同的,都是將一組數字(例如1~N)打亂重新排列,只
不過洗撲克牌多了一個花色判斷的動作而已。
解法:
初學者通常會直接想到,隨機產生1~N的亂數并將之存入陣列中,后來產生的亂數存入陣列
前必須先檢查陣列中是否已有重復的數字,如果有這個數就不存入,再重新產生下一個數,運
氣不好的話,重復的次數就會很多,程式的執行速度就很慢了,這不是一個好方法。
以1~52的亂數排列為例好了,可以將陣列先依序由1到52填入,然后使用一個回圈走訪陣列,
并隨機產生1~52的亂數,將產生的亂數當作索引取出陣列值,并與目前陣列走訪到的值相交換,
如此就不用擔心亂數重復的問題了,陣列走訪完畢后,所有的數字也就重新排列了。
至于如何判斷花色?這只是除法的問題而已,取商數判斷花色,取余數判斷數字,您可以直接
看程式比較清楚。

#include <stdio.h>

include <stdlib.h>

include <time.h>

define N 52

int main(void) { int poker[N + 1]; int i, j, tmp, remain; // 初始化陣列 for (i = 1; i <= N; i++) poker[i] = i; srand(time(0)); // 洗牌 for (i = 1; i <= N; i++) { j = rand() % 52+1; tmp = poker[i]; poker[i] = poker[j]; poker[j] = tmp; } for (i = 1; i <= N; i++) { // 判斷花色 switch ((poker[i] - 1) / 13) { case 0: printf("桃"); break; case 1: printf("心"); break; case 2: printf("磚"); break; case 3: printf("梅"); break; } // 撲克牌數字 remain = poker[i] % 13; switch (remain) { case 0: printf("K "); break; case 12: printf("Q "); break; case 11: printf("J "); break; default: printf("%d ", remain); break; } if (i % 13 == 0) printf("\n"); } return 0; }</pre>

 本文由用戶 wdey 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!