void shuffle_3(int data[], int length) { #define COUNT 54 int i = 0, idx1 = 0, idx2 = 0; for(i = 0; i < COUNT; i++) { idx1 = fix_random(0, length - 1); idx2 = fix_random(0, length - 1); swap(&data[idx1], &data[idx2]); } return; }
void shuffle_4(int data[], int length) { int i = 0, idx = 0; for(i = 0; i < length; i++) { idx = fix_random(0, length - 1); swap(&data[idx], &data[i]); } return; }
void shuffle_5(int data[], int length) { int i = 0, idx = 0; for(i = 0; i < length; i++) { idx = fix_random(0, i); swap(&data[idx], &data[i]); } return; }
实际排列的可能情况有N!种;算法四的输出有N*N中,算法五的输出有N!种,而且N*N不能被N!整除,所以经过算法四所定义的牌与牌之间的交换程序,很可能一张牌被换来换去又被换回到原来的位置,所以这个算法不是最优的。而算法五输出的可能组合恰好是n!种,所以这个算法才是完美的。
将54张扑克牌按顺序编号,0和53为大王和小王,1~12为黑色,13~24为红色,25~36为花色,37~52为方片
#include <stdio.h> #include <stdlib.h> #include <string.h> inline void swap(int *a, int *b) { int tmp = 0; tmp = *a; *a = *b; *b = tmp; } inline int fix_random(int start, int end) { return start + rand()%(end -start + 1); } void init_card(int data[], int length) { int i = 0; for(i = 0; i < length; i++) { data[i] = i; } return; } void out_card(int data[], int length) { #define NUMPERLINE 6 int i = 0; for(i = 0; i < length; i++) { printf("%d\t",data[i]); if( (i+1) % NUMPERLINE == 0) { printf("\n"); } } printf("\n"); return; } #define CARD_NUM 54 int main() { int *data = (int *)malloc(CARD_NUM * sizeof(int)); if(NULL == data) { printf("Failed to alloc memory for card.\n"); return 0; } memset(data, 0x0, CARD_NUM * sizeof(int)); init_card(data, CARD_NUM); printf("Out card:\n"); out_card(data, CARD_NUM); shuffle_4(data, CARD_NUM); printf("Shuffle, out card:\n"); out_card(data, CARD_NUM); shuffle_5(data, CARD_NUM); printf("Shuffle, out card:\n"); out_card(data, CARD_NUM); shuffle_3(data, CARD_NUM); printf("Shuffle, out card:\n"); out_card(data, CARD_NUM); free(data); }