C语言实现-“洗 扑克牌”程序 算法(详解)

1.问题引入

        我们对“扑克牌”这个词并不陌生,作为一种娱乐活动被大众所熟知。那么,每一局结束后,除了人工洗牌,我们接触到的软件、小程序中如何实现的“洗牌”呢?其实,洗扑克牌的原理与乱数排列是相同的,都是将一组数字(如 1~N)打乱重新排列,只不过洗扑克牌多了一个花色判断的过程。

2.问题分析

        一想到“随机”,大部分人想到的是利用产生随机数的方式 随机产生1~N的乱序数字并将之存入数组中,之后对后续产生的乱序数字存入数组前先检查阵列中是否已有重复的数字,如果数组中有这个数就不存入数组,再重新产生下一个数。在糟糕的情况下,如果多次产生的乱序数字都与数组中的数字重复,那么则会导致程序的执行速度变得缓慢,影响代码运行效率,因此这并不是一个很好的办法,如何进行改进呢?

        我们以1-52的数字的乱数排序进行分析。首先,我们可以将数组按顺序从1-52依次填入,然后采用一个循环访问数组并随机产生1-52的乱序数,之后将产生的乱序数当作索引取出数组值,并与目前访问到的数组值交换 ,这样就不会产生重复的数字。也就是通过交换数组对应的值,即满足产生的数是乱序的,也提到了代码运行效率。

        那么,如何判断牌的花色呢?我们只需要借助除法就可以解决这个问题,取商数判断花色,取余数判断数字。

3.代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 52

int main() {
	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; //从序号1开始产生52个随机数
		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;
}

4.运行效果

写在最后:

        读两遍下来,如果仍然有不清楚的地方,可以再来一遍。

        如果你有其他感到困惑的问题,欢迎留言。

  • 9
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等日出看彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值