打乱数组

Posted 时光孤岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打乱数组相关的知识,希望对你有一定的参考价值。

方法一

从已知数组中随机一个数,然后加入到另一个数组中,在加入之前,先检查是否已经加入过。

这种方法有很大运气成分,且数据越大,效率越低,超过一定数目,则程序几乎无法执行,会一直卡在那里,代码:

技术分享
    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;  
     }  
View Code

 

方法二

这种方法是我遇到这个问题就想到的,思路就是:先随机出已知数组的下标值,然后取出这个数放到另一个数组中,再从已知数组中删除这个数。这种方法的运算次数是根据数组长度而定的,缺点是 大部分运算都耗在删除的判断上,主要是因为 数组不像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;  
}  
View Code

 

 方法三

每次从已知数组随机一个数,然后将数组的最后一个值 赋值给前面随机到的数的位置上,然后将长度-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;  
}

 4 将随机得到的这个数和数组最后一个数交换。然后再从array.length-1中随机一个数和array.length-1交换。

测试代码

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;  
}

 


结果:

 
    1. m1 运算次数  = 51  
    2. 10 7   
    3. m2运算次数  = 65  
    4. 10 4   
    5. m3运算次数  = 10  
    6. 10 4  


以上是关于打乱数组的主要内容,如果未能解决你的问题,请参考以下文章

javascript随机打乱数组

随机打乱数组及Fisher–Yates shuffle算法详解

p105 打乱数组(leetcode 384)

js实践用 js 封装java shuffle函数(打乱数组下标方法)

如何在给定范围内创建一个随机打乱数字的 int 数组 [重复]

将数组 A 复制到数组 B 中,将其中一个数组打乱,但两个数组都被打乱 [重复]