[置顶] 给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。(思路3)
给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。 (思路3)
思路2(点击打开链接)方法的缺陷已经详细的说明,为了解决充分随机的问题,即把所有的牌都必须移动(如果移动后又回到原位,那也是正常的)。
因此本题采用的方法是:依次的把1到54张牌与数组中任意元素交换。
无论如何,这种方法把所有的牌都移动过。时间复杂度是O(n)。能够解决充分随机的问题。
//给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define CARDS_NUM 54 //打印一副牌中的内容 void printCards(int *cards) { int i=0; int flag=0; for(i=0;i<CARDS_NUM;i++) { if(flag==13) { printf("\n"); flag=1; } else { flag++; } printf("%3d",*cards); cards++; } printf("\n"); } //创建一副1到54的牌,并存储在数组中 int * createCards(int *cards) { int i=0; for(i=0;i<CARDS_NUM;i++) { *(cards+i)=i+1; } return cards; } //对数组中的两个元素交换,采用异或 int * swap(int *cards,int i,int j) { if(i=j) { //do nothing } else { *(cards+i)=*(cards+i)^*(cards+j); *(cards+j)=*(cards+j)^*(cards+i); *(cards+i)=*(cards+i)^*(cards+j); } return cards; } void main() { int i=0; int p=0; int cards[CARDS_NUM]={0}; printf("一副牌有54张牌:1——13表示黑桃;14——26表示红桃;\n"); printf(" 27——39表示梅花;40——52表示方块;\n"); printf(" 51表示小王;52表示大王。\n\n"); createCards(cards); printf("原始有序牌为:\n"); printCards(cards); srand(time(0)); for(i=0;i<CARDS_NUM;i++) { p=rand()%54; swap(cards,p,i); //每次随机找一个数依次和0到53中的元素交换 } printf("\n随机洗牌后的结果是:\n"); printCards(cards); }