将一数组乱序排列的三种方法
2012-03-26 22:53
501 查看
游戏中遇到这样的问题,需要将一组已知的数据打乱,按照以前和现在的做法,总结了以下方法。
方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :))
从已知数组中随机一个数,然后加入到另一个数组中,在加入之前,先检查是否已经加入过。
这种方法有很大运气成分,且数据越大,效率越低,超过一定数目,则程序几乎无法执行,会一直卡在那里,代码:
方法二,这种方法是我遇到这个问题就想到的,思路就是:先随机出已知数组的下标值,然后取出这个数放到另一个数组中,再从已知数组中删除这个数。这种方法的运算次数是根据数组长度而定的,缺点是 大部分运算都耗在删除的判断上,主要是因为 数组不像list那样,能删除一个指定位置的值。代码:
方法三, 这种方法就很巧妙了,是在c 的代码中看到,翻译成了java代码,它的巧妙在于:每次从已知数组随机一个数,然后将数组的最后一个值 赋值给前面随机到的数的位置上,然后将长度-1,再从原数组下标-1的数组中随机。 运算次数就是数组长度,这种方法真的很聪明啊,以下是代码:
测试下代码:
结果:
第三种方法还是值得学习的,大家如果有其它好的方法和思路欢迎补充~~
方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :))
从已知数组中随机一个数,然后加入到另一个数组中,在加入之前,先检查是否已经加入过。
这种方法有很大运气成分,且数据越大,效率越低,超过一定数目,则程序几乎无法执行,会一直卡在那里,代码:
package com.test; import java.util.Random; public class TestArray { public static int runCount =0;//用于记录方法运算次数 public int [] m1(int [] arr){ Random ran = new Random(); int length = arr.length; int [] newArr = new int[length]; int count =0; while (true) { runCount ++; int r = ran.nextInt(length)+1; if(!exist(r, newArr)){ newArr [count] = r; count++; } if(count==length){ break; } } System.out.println("m1 运算次数 = "+runCount); return newArr; } public static boolean exist(int a,int [] arr){ for (int i = 0; i < arr.length; i++) { if(arr[i] ==a){ return true; } } return false; }
方法二,这种方法是我遇到这个问题就想到的,思路就是:先随机出已知数组的下标值,然后取出这个数放到另一个数组中,再从已知数组中删除这个数。这种方法的运算次数是根据数组长度而定的,缺点是 大部分运算都耗在删除的判断上,主要是因为 数组不像list那样,能删除一个指定位置的值。代码:
//----------------------------------------------- public int [] m2(int [] arr){ Random ran = new Random(); int [] newArr = new int[arr.length]; int k = 0; while (arr.length>0) { runCount++; int index = ran.nextInt(arr.length);//随即数组下标 newArr[k++] = arr[index]; arr = removeElement(arr[index], arr); } System.out.println("m2运算次数 = "+runCount); return newArr; } public int [] removeElement(int ele,int [] arr){ int [] arr2 =new int[arr.length-1]; int k = 0; for (int i = 0; i < arr.length; i++) { runCount++; if(arr[i]!=ele){ arr2[k++] = arr[i]; } } return arr2; }
方法三, 这种方法就很巧妙了,是在c 的代码中看到,翻译成了java代码,它的巧妙在于:每次从已知数组随机一个数,然后将数组的最后一个值 赋值给前面随机到的数的位置上,然后将长度-1,再从原数组下标-1的数组中随机。 运算次数就是数组长度,这种方法真的很聪明啊,以下是代码:
//----------------------------------------------- public int [] m3(int [] arr) { int [] arr2 =new int[arr.length]; int count = arr.length; int cbRandCount = 0;// 索引 int cbPosition = 0;// 位置 int k =0; do { runCount++; Random rand = new Random(); int r = count - cbRandCount; cbPosition = rand.nextInt(r); arr2[k++] = arr[cbPosition]; cbRandCount++; arr[cbPosition] = arr[r - 1];// 将最后一位数值赋值给已经被使用的cbPosition } while (cbRandCount < count); System.out.println("m3运算次数 = "+runCount); return arr2; }
测试下代码:
// ---------------------------------------------- public static void main(String[] args) { int[] arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i + 1; } TestArray t = new TestArray(); arr = t.m1(arr); print(arr); arr = t.m2(arr); print(arr); arr = t.m3(arr); print(arr); } public static void print(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); runCount = 0; }
结果:
m1 运算次数 = 51 3 10 2 1 5 9 6 8 4 7 m2运算次数 = 65 1 3 8 2 10 5 9 6 7 4 m3运算次数 = 10 10 7 8 3 1 5 6 9 2 4
第三种方法还是值得学习的,大家如果有其它好的方法和思路欢迎补充~~
相关文章推荐
- 12、Java入门—将一数组乱序排列的三种方法 (快速洗牌的小算法)
- 将一数组乱序排列的三种方法
- 字符串或数组全排列的三种方法
- AS3清空数组的三种方法
- 第十四周 冒泡法 按升序排列数字 采用数组的方法
- JavaScript中实现最高效的数组乱序方法
- JavaScript中数组去除重复的三种方法
- Javascript 三种合并数组方法!
- JS判断数组中是否有重复值得三种方法
- java创建数组的三种方法
- js数组去重的三种常用方法总结
- 数组中的方括号([ ])三种使用方法
- python数组遍历三种实用方法
- 生成1~n的排列的三种方法
- JS判断一个数组中是否有重复值的三种方法
- JavaScript定义数组的三种方法(new Array(),new Array('x','y')
- 数组乱序排列
- JS实现数组按升序及降序排列的方法
- 学习笔记之js数组去重的方法三种