随机 打乱 数组 List 洗牌算法 shuffle

在游戏研发过程中,多少会遇到这样的需求, 在一堆数据中随机打乱后再分配出去。这个是比较典型的洗牌算法,在Java中提供了这样的API:Collections.shuffle(),C++中也提供了std::random_shuffle,都可以随机的打乱一个List。现在对一个数组进行随机打乱。参考了Java中Collections.shffle()。

 

package com.xd100;

import java.util.Random;

public class RandomArray {

	private RandomArray(int[] array) {
		for (int i = 0; i < array.length; i++){
			array[i] = i;
		}
	}
	
	public static void main(String[] args) {
		int array [] = new int[10];
		RandomArray ra = new RandomArray(array);
		ra.printArray(array);
		ra.random(array);
		ra.printArray(array);
		
		Integer[] array2 = {0,1, 2, 3, 4, 5, 6, 7, 8, 9 };
		ra.random(array2);
		for (int i = 0; i < array2.length; i++) {
			System.out.print(array2[i].intValue() + " ");
		}
	}
	
	/**
	 * 打印数组数据
	 * @param array
	 */
	private void printArray(int[] array) {
		for (int i = 0; i < array.length; i++){
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}
	
	private void random(int[] array) {
		Random rand = new Random();
		for (int i = array.length; i > 1; i--) {
			// 从0到i之间随机取一个值,跟i处的元素交换,参考Collections.shuffle();
			swap(array, i - 1, rand.nextInt(i));
		}
	}
	
	/**
	 * 交换位置
	 */
	private void swap(int[] array, int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	
	private Integer[] swap(Integer[] array, int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
		return array;
	}

	private Integer[] random(Integer[] array) {
		Random rand = new Random();
		for (int i = array.length; i > 1; i--) {
			// 从0到i之间随机取一个值,跟i处的元素交换,参考Collections.shuffle();
			array = swap(array, i - 1, rand.nextInt(i));
		}
		return array;
	}
}

 

 

     java自带API的实现如下:

     

package com.xd100.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ShuffleTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++)
            list.add(new Integer(i));
        System.out.println("打乱前:");
        System.out.println(list);

        for (int i = 0; i < 5; i++) {
            System.out.println("第" + i + "次打乱:");
            Collections.shuffle(list);
            System.out.println(list);
        }
    }
}

 

     在游戏研发过程中,往往还有这个业务需求,就是数据抽取,比如在1-9个数中,随机抽取3个数据,并且3个数据不重复。这个有2中实现方法,1种是打乱1-9个数,抽取前三个数,另外是随抽取1-9,去重获得3个数。

    

	/**
	 * 数据抽取 
	 * @param max 抽取是范围(1-max的整数值范围)
	 * @param randomNum 抽取个数
	 * @return
	 */
	public static int[] extract(int max,int randomNum){
		int i = 0;// 计数器 指示当前要填加到的数组下标,并指示当前已经添加了几个数
		boolean flag;// 判断是否重复的辅助变量
		int[] num = new int[randomNum];// 存储randomNum个生成的数据
		while (i < randomNum) {
			// 生成一个随机数
			int j = (int) (Math.random() * max + 1);
			// 将辅助变量设置为true 表示可以添加到数组
			flag = true;
			// 循环判断是否重复
			for (int n = 0; n < i; n++) {
				// 如果重复,设置辅助变量为false且跳出循环,如果不重复则会一直将已添加的数组历遍一次
				if (num[n] == j) {
					flag = false;
					break;
				}
			}
			// 如果可以添加 添加到存储数组 并将计数器i自加1
			if (flag) {
				num[i] = j;
				i++;
			}
		}
		return num;
	}

 

   

你可能感兴趣的:(shuffle)