洗牌算法java 剑指_扑克牌的完美洗牌算法

思路:

递归思想。我们有n张牌,不妨先假设有一个洗牌函数shuffle(....),能完美的洗出n-1张牌 。拿第n张牌来打乱前面n-1的洗牌顺序,从而得到n张牌的最终结果。

代码如下:

#include 

#include 

using namespace std;

//随机指定区域内的数

int MyRand(int low, int high)

{

return low + rand() % (high - low + 1);

}

int* shuffle(int* cards, int n)

{

if (n <= 0)

return cards;

shuffle(cards, n - 1);

int rand = MyRand(0, n);

int temp = cards[rand];

cards[rand] = cards[n];

cards[n] = temp;

return cards;

}

int main()

{

for (int k = 1; k <= 10; k++)

{

int cards[52] = {

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,

14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,

36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,

47, 48, 49, 50, 51, 52,

};

cout <

shuffle(cards, 52);//  洗牌

for (int i = 1; i <= 52; i++)

{

cout <

if (i % 13 == 0)

cout <

}

}

cout <

system("PAUSE");

return 0;

}

输出结果:

4 18 17 14 36 6 41 20 26 29 1 39 12

51 48 49 13 27 10 34 31 47 8 52 45 35

40 4 38 25 3 24 19 22 21 44 32 30 15

50 16 2 33 11 5 7 23 46 42 37 43 9

11 36 41 28 48 35 29 30 10 15 40 44 31

26 33 8 7 12 32 23 14 46 45 6 21 24

3 25 1 13 18 20 39 52 5 4 47 17 42

50 16 2 37 38 9 19 43 27 34 28 22 51

2 17 33 13 19 32 44 8 12 23 52 51 45

4 26 1 14 38 3 43 21 39 11 9 42 46

35 34 31 47 29 41 18 25 40 48 6 10 30

36 15 24 49 37 5 27 28 50 49 16 20 22

31 12 5 39 35 47 9 23 16 41 20 24 48

21 11 30 13 7 43 38 49 40 46 19 50 52

44 14 6 45 18 1 17 32 4 28 27 8 2

36 33 15 42 34 29 25 37 10 26 51 22 7

47 23 11 36 18 40 25 32 39 7 42 4 22

48 49 33 3 30 43 41 12 6 15 24 37 28

27 50 51 19 16 29 3 5 2 26 10 35 52

1 38 45 34 21 13 31 17 14 46 9 8 44

........

从结果来看上去很完美,剩下就是要在随机函数上做文章了,如果有一个完美的随机数发生器,那么这就是一个完美的洗牌算法。

通常递归的方法都能最换成迭代法,代码如下:

void shuffle2(int* cards, int n)

{

// 随机i-1中的任意一个数与i交换

for (int i = 0; i 

{

int rand = MyRand(0, i);

int temp = cards[rand];

cards[rand] = cards[i];

cards[i] = temp;

}

}

Done!还不赖~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值