在游戏研发过程中,多少会遇到这样的需求, 在一堆数据中随机打乱后再分配出去。这个是比较典型的洗牌算法,在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; }