C++ 洗牌算法的实现

大家在玩斗地主的时候,每次都是随机发牌,每个人拿到手的牌都是和上一次不一样的。那么电脑是如何做到随机的呢?
首先大家想到的就是采用系统本身的随机算法产生的随机数,每次都根据产生的随机数来获取不同位置的。

举个简单的例子:0-9这10个数,如何让这10个数随机排序呢,而且保证每次出现的概率都是一样的?
1.首先初始化两个数组含有10个整数的数组A和数组B,A数组用来存放原始数据,B数组用来存放随机的排序后的数
2.根据随机产生的位置来取A数组中对应位置整数并且依次放到B数组中(例如:第一次产生的随机数是3,则把A[3]中的整数取出后放到B[0]中)
3.把第一次A数组中取出的整数和A数组中最后一个位置的整数交换(第二取出的数和倒数第二个位置的数交换,第三次取出的数和倒数第三个位置的数交换…以此类推),这样完成一次随机取数。
先看效果:
在这里插入图片描述

#pragma once

//随机排序类

class RandomNumber {
public:
	RandomNumber();
	~RandomNumber();

	void setMaxNumber(int maxNum);

	int*getRandNumber(int&countNumber);
private:
	int _maxNumber = -1;//最大的整数
	int* _orgNum = nullptr;//初始数组
	int* _randNum = nullptr;//随机排序后的数组
};
#include "RandomNumber.h"
#include <cstdlib>

RandomNumber::RandomNumber() {
}


RandomNumber::~RandomNumber() {
}

void RandomNumber::setMaxNumber(int maxNum) {
	_maxNumber = maxNum;

	if (_orgNum !=nullptr || _randNum!=nullptr){
		delete _orgNum;
		_orgNum = nullptr;

		delete _randNum; 
		_randNum = nullptr;
	}
	_orgNum = new int[_maxNumber];
	_randNum = new int[_maxNumber];

	for (int i =0;i< _maxNumber; i++){
		_orgNum[i] = i;
		_randNum[i] = i;
	}
}

int* RandomNumber::getRandNumber(int&countNumber) {
	countNumber = _maxNumber;
	int temp = -1;
	int maxRand = _maxNumber;
	for (int i = 0; i < _maxNumber; i++) {
		//1.随机生成 0 和 maxRand-1之间的整数
		int randOne = rand() % maxRand;

		//2.把_orgNum的位置randOne的数放到需要排序的数组中
		_randNum[i] = _orgNum[randOne];

		//3.把_orgNum的位置randOne的数和maxRand-1的位置的数交换
		temp = _orgNum[randOne];
		_orgNum[randOne] = _orgNum[maxRand - 1];
		_orgNum[maxRand - 1] = temp;

		//4.缩小随机数的范围
		maxRand--;
	}
	return _randNum;
}

源码下载
aaa

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wb175208

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

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

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

打赏作者

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

抵扣说明:

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

余额充值