【算法】Fisher-Yate洗牌算法

news/2024/7/5 4:24:22

算法描述

  1. Fisher-Yates 洗牌算法(Fisher-Yates Shuffle)是一种用于随机打乱数组或列表元素顺序的算法,以获取随机排列。这个算法是由 Ronald A. Fisher 和 Frank Yates 于 1938 年开发的,用于生成无偏的、随机的排列顺序。

  2. Fisher-Yates 洗牌算法的基本思想是从数组中的最后一个元素开始,逐步将当前位置的元素与数组中之前的位置中的一个随机元素进行交换,直到第一个元素。这个过程确保了每个元素都有相等的机会出现在任何一个位置上,从而获得了真正的随机性。

具体步骤如下:

从数组末尾开始,选择一个随机位置(可以是前面任何一个位置,包括当前位置)。
将当前位置的元素与随机位置的元素进行交换。
重复步骤 1 和 2,逐步向前,直到到达数组的第一个元素。
通过多次重复这个过程,数组的元素就会被随机打乱,从而实现了洗牌效果。

Fisher-Yates 洗牌算法是一种简单且高效的洗牌方法,适用于需要随机排列的各种情况,如随机抽样、模拟和算法中的随机化等。

#ifndef ALGO_SHUFFLE_H__
#define ALGO_SHUFFLE_H__

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

namespace alg {
	/**
	 * shuffle the 'list' of length 'len'
	 */
	template<typename T>
		static void shuffle(T * list, int len) {
			srand(time(NULL));
			int i = len, j;
			T temp;

			if ( i == 0 ) return;
			while ( --i ) {
				j = rand() % (i+1);
				temp = list[i];
				list[i] = list[j];
				list[j] = temp;
			}
		}
}

#endif //

demo

#include <stdio.h>
#include <stdlib.h>

#include "generic.h"
#include "shuffle.h"
using namespace alg;
int main()
{
	const int MAX_ELEMENTS = 10;
	int list[MAX_ELEMENTS];

	int i = 0;

	// generate random numbers and fill them to the list
	for(i = 0; i < MAX_ELEMENTS; i++ ){
		list[i] = i;
	}
	printf("The list before Shuffle is:\n");
	printlist(list,MAX_ELEMENTS);

	// shuffle the list
	shuffle<int>(list,MAX_ELEMENTS);

	// print the result
	printf("The list after using Yates' shuffle algorithm:\n");
	printlist(list,MAX_ELEMENTS);
	return 0;
}

http://lihuaxi.xjx100.cn/news/1445912.html

相关文章

W6100-EVB-PICO 做UDP Server进行数据回环测试(七)

前言 前面我们用W6100-EVB-PICO 开发板在TCP Client和TCP Server模式下&#xff0c;分别进行数据回环测试&#xff0c;本章我们将用开发板在UDP Server模式下进行数据回环测试。 UDP是什么&#xff1f;什么是UDP Server&#xff1f;能干什么&#xff1f; UDP (User Dataqram P…

快速了解steam、csgo游戏搬砖,steam搬砖项目分享

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 我相信你对移动游戏并不陌生&#xff0c;但有些朋友不应该听说过steam和csgo这个词。steam是…

【C语言】每日一题(寻找数组的中心下标)

寻找数组的中心下标&#xff0c;链接奉上 方法 暴力循环前缀和 暴力循环 ​​​​​​​思路&#xff1a; 依旧是我们的老朋友&#xff0c;暴力循环。 1.可以利用外层for循环&#xff0c;循环变量为数组下标&#xff0c;在循环内分别求出下标左边与右边的sum 2.在边界时讨论&…

EB配置------PORT(一)

今天学习了PortPinInputPullResistor 这个配置。 虽然它配置为输出后显示不可更改&#xff0c;但是它默认的配置依然有效。 该参数允许为所选端口引脚配置内部拉电阻[向上/向下]。 注意&#xff1a;此参数的默认值设置为相应SFR的重置值。 PORT_PIN_IN_NO_PULL&#xff1a;…

【CTF-MISC】眼见非实(掌握各类文件头)

题目链接&#xff1a;https://ctf.bugku.com/challenges/detail/id/5.html 下载是一个.docx文档&#xff0c;用010 Editor打开查看文件头发现应该是zip文件&#xff0c;修改后缀后解压&#xff0c;查找flag。 各类常用文件头如下表所示。 文件类型文件头JPEG (jpg)FFD8FFE1PNG…

日常BUG——SpringBoot关于父子工程依赖问题

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 在父子工程A和B中。A依赖于B&#xff0c;但是A中却无法引入B中的依赖&#xff0c;具体出现的…

盒子阴影效果与环绕阴影

box-shadow 在前端样式里面&#xff0c;最常见的一中效果之一就是阴影&#xff0c;好的阴影可以瞬间给人一种高端的用户体验&#xff0c;今天简单总结下这个样式的语法与使用方法。 语法 box-shadow的语法其实是比较简单好记的&#xff0c;我们按照最全面的写法来看 x轴偏移…

Kotlin CompletableDeferred 入门

在 Kotlin 中&#xff0c;CompletableDeferred 是一个用于异步编程的类&#xff0c;它提供了一种实现异步操作和等待操作结果的方式。 CompletableDeferred 是 Deferred 接口的具体实现之一&#xff0c;可以用于表示一个可能会在将来完成的操作。它提供了以下主要功能&#xf…