[置顶] 给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。(思路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);
}


 


 

posted @ 2013-03-27 22:14  javawebsoa  Views(319)  Comments(0Edit  收藏  举报