Java中打乱一个数组的2种公平算法分享

公平算法,打乱数组

这是前几天面试的时候遇见的一道题目,看到这个题首先想到了洗牌程序:

方法一:洗牌程序原理

在java.util包中的Collections类中的 shuffle方法,现在手工实现以下代码如下:

package test.ms;

import java.util.Random;

public class Redistribute2 {
	public static void main(String[] args) {

		//define the array
		int[] s = {1,5,4,3,6,9,8,7,0,8,5,6,7,2};

		// before redistribute output
		System.out.println("before redistribute:");
		for(int i = 0 ; i<s.length; i++){
			System.out.print(s[i]+" ");
		}

		// invoke the method
		shuffle(s,new Random());

		System.out.println();

		// after redistribute output
		System.out.println("after redistribute:");
		for(int i = 0 ; i<s.length; i++){
			System.out.print(s[i]+" ");
		}
	}

	// using the random get the random number
	public static  void  shuffle(int[] array, Random random){

		for(int i = array.length; i >= 1; i--){

			swap(array,i-1,random.nextInt(i));
		}
	}

	// the two number swap  in the array
	public static void swap(int[] array, int i , int j){

		int temp = array[i];

		array[i] = array[j];

		array[j] = temp;

	}
}

swap方法用于交换数组中的两个数,  shuffle方法 用于 根据随机源 生成的随机数进行交换。
输出结果如下:

before redistribute:
1 5 4 3 6 9 8 7 0 8 5 6 7 2
after redistribute:
9 8 7 8 0 6 1 6 5 5 2 3 7 4 

方法二:生成随机索引交换

该方法利用Set集合的特性:Set集合中的数据不重复,生成数组的索引,根据生成的索引进行交换数据。

实现方式如下:

package test.ms;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;

public class Redistribute {

	public static void main(String[] args) {
		int[] s = {1,5,4,3,6,9,8,7,0,8,5,6,7,2};
		redistribute(s);
	}
	public static void  redistribute(int[] s){
		Random  random = new Random();

		Set<Integer> set = new LinkedHashSet<Integer>();

		// redistribute the  index
		while(true){
			int t =random.nextInt(s.length);
			set.add(t);
			if(set.size()== s.length)
			break;
		}
		System.out.println("before redistribute:");
		for(int i = 0 ; i<s.length; i++){
			System.out.print(s[i]+" ");
		}
		System.out.println();
		System.out.println("redistribute the index ");System.out.println(set);

		int [] out = new int[s.length];

		int count = 0;

		for(Iterator<Integer> iterator = set.iterator(); iterator.hasNext();){
			out[count] = s[iterator.next()];
			count++;
		}

		// out the result;
		System.out.println("after redistribute:");
		for(int i = 0 ; i<s.length; i++){
			System.out.print(out[i]+" ");
		}
	}

}

这个方法首先生成索引,然后根据新索引进行数据交换,代码都写在main方法里了,不是太好。

生成结果如下:

before redistribute:
1 5 4 3 6 9 8 7 0 8 5 6 7 2
redistribute the index
[6, 2, 9, 1, 10, 5, 11, 4, 12, 3, 7, 8, 0, 13]
after redistribute:
8 4 8 5 5 9 6 6 7 3 7 0 1 2 

关于随机数的生成,用了java类中的随机数的生成的工具类,这个随机类需要单独研究一下。

(0)

相关推荐

  • java求100之内的素数(质数)简单示例

    质数又称素数.一个大于1的自然数,如果除了1和它自身外,不能被其他自然数整除的数:否则称为合数.根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积:而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的.下面是一个java求100之内的素数简单示例 复制代码 代码如下: public class test { public static void main(String[] args) {  int i,n,k=0;     for (n = 3; n

  • Java数据结构及算法实例:汉诺塔问题 Hanoi

    /** * 汉诺塔大学的时候就学过,但是根本没搞明白,唯一知道的就是要用递归的方法来求解. * 问题描述: * 有三根杆子A,B,C.A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小. * 要求按下列规则将所有圆盘移至C杆: * 1.每次只能移动一个圆盘: * 2.大盘不能叠在小盘上面. * 提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆, * 但都必须尊循上述两条规则. * 问:如何移?最少要移动多少次? * 解决方法: * 假设只有2个盘子,柱子分别是A, B, C柱

  • java数据结构与算法之双向循环队列的数组实现方法

    本文实例讲述了java数据结构与算法之双向循环队列的数组实现方法.分享给大家供大家参考,具体如下: 需要说明的是此算法我并没有测试过,这里给出的相当于伪代码的算法思想,所以只能用来作为参考! package source; public class Deque { private int maxSize; private int left; private int right; private int nItems; private long[] myDeque; //constructor p

  • Java使用分治算法实现排序数索引功能示例【二分搜索】

    本文实例讲述了Java使用分治算法实现排序数索引功能.分享给大家供大家参考,具体如下: /** * Find the first q and return the index * First method is brutal force * Second may * be Divid and Conquer * * @author open201 * */ public class Ono { /** * f(n) = s.length = n; * * @param s * @param q

  • Java实现分解任意输入数的质因数算法示例

    本文实例讲述了Java实现分解任意输入数的质因数算法.分享给大家供大家参考,具体如下: 分解任意输入数的质因数: 质因数概念:任何一个合数都可以写成几个质数相乘的形式.其中每个质数都是这个合数的因数,叫做这个合数的分解质因数.分解质因数只针对合数. 例如:12 = 2x2x3  18 = 2 x 3 x 3等等 下面来讲解一下这个算法的思路:第一:我们首先写一个求素数的函数:第二;我们做一个分解质因数的函数,然后在其中引入素数函数来判断是否为素数: 下面给出代码(仅供参考): package j

  • Java将一个正整数分解质因数的代码

    程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成: 1.如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可. 2.如果n <> k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你,重复执行第一步. 3.如果n不能被k整除,则用k+1作为k的值,重复执行第一步. 程序设计: public class exp2{ public exp2(){} public void fengjie(int n){ for(int i=2;i<=

  • 史上最全的java随机数生成算法分享

    复制代码 代码如下: String password = RandomUtil.generateString(10); 源码如下: 复制代码 代码如下: package com.javaniu.core.util;import java.util.Random;public class RandomUtil { public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS

  • JavaScrpt判断一个数是否是质数的实例代码

    废话不多说了,直接给大家贴代码了 <script> //1.非正则实现 function isPrime(num) { // 不是数字或者数字小于2 if(typeof num !== "number" || !Number.isInteger(num)) { // Number.isInterget 判断是否为整数 return false } //2是质数 if(num == 2) { return true } else if(num % 2 == 0) { //排除

  • Java对数组实现选择排序算法的实例详解

    一. 算法描述     选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,至此选择排序完成. 以下面5个无序的数据为例: 56 12 80 91 20(文中仅细化了第一趟的选择过程) 第1趟:12 56 80 91 20 第2趟:12 20 80 91 56 第3趟:12 20 56 91 80 第4趟

  • Java实现求小于n的质数的3种方法

    质数概念 质数,又称素数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因数的数). 最小的素数是2,也是素数中唯一的偶数:其他素数都是奇数.质数有无限多个,所以不存在最大的质数. 一:根据定义去求解: 也是最笨的方式,效率比较低: package test.ms; public class FindPrime { // find the prime between 1 to 1000; public static void main(Str

  • java生成抽样随机数的多种算法

    本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示. 概述: 这里你是不是会说,生成随机数有什么难的?不就是直接使用Java封装好了的random就行了么?当然对于一般情况下是OK的,而且本文要说明的这些算法也是基于这个random库函数的. 本文主要是针对抽样这一行为进行的,而抽样本身有一个隐含的规则就是不要有重复数据.好了,有了这些说明.你可以先尝试着用一些自己的想法来实现不重复地生成随机数. 算法尝试: 一些好的算法出现,往往伴随着一些不那么好的算法.但是对于效果不太好的算法

  • 常用数字签名算法RSA与DSA的Java程序内实现示例

    RSA加密算法 我们来回顾一下RSA的加密算法.我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法. RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法). 密钥生成算法以安全常数作为输入,输出一个公钥PK,和一个私钥SK.安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关.越大,质数p一般越大,保证体制有更高的安全性.在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质

随机推荐