将一数组乱序排列的三种方法
来源:互联网 发布:英语听力口语软件 编辑:程序博客网 时间:2024/05/16 00:36
游戏中遇到这样的问题,需要将一组已知的数据打乱,按照以前和现在的做法,总结了以下方法。
方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :))
从已知数组中随机一个数,然后加入到另一个数组中,在加入之前,先检查是否已经加入过。
这种方法有很大运气成分,且数据越大,效率越低,超过一定数目,则程序几乎无法执行,会一直卡在那里,代码:
- 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
第三种方法还是值得学习的,大家如果有其它好的方法和思路欢迎补充~~
0 0
- 将一数组乱序排列的三种方法
- 将一数组乱序排列的三种方法
- 12、Java入门—将一数组乱序排列的三种方法 (快速洗牌的小算法)
- 0-99的不重复乱序排列数组
- 字符串或数组全排列的三种方法
- 使用数组实现排列乱序
- JavaScript 数组乱序方法
- Javascript数组完全随机排列(数组乱序)
- 将数组升序排列的方法与冒泡排序
- SQL 巧妙的乱序排列
- 集合乱序排列
- 三整数排列的3种方法
- 字符串反序排列的三种方法
- android中对一个集合中的数据进行乱序排列的一些方法
- 将数组里的成员升序排列
- Java 5*5数组的三种排列例子
- 数据如何乱序排列
- Anagrams 寻找相同的乱序的字母排列
- CStdioFile的用法
- Ajax 传中文参数乱码问题(Post和Get方式)
- 0x0D和0x0A
- 汇编语言中PTR的含义
- MFC 文件,文件夹操作
- 将一数组乱序排列的三种方法
- c++接口定义及实现举例
- HDOJ 2063 二分图匹配
- android应用完全退出的多种方式
- hibernate 的cache管理
- HDOJ 1020 一次AC代码
- error: 'for' loop initial declarations are only allowed in C99 mode 的原因及解决办法
- 图形学_画线算法(DDA、Bresenham)
- 图形学_圆的扫描转换