java打乱数组顺序

  • import java.util.*;  
  •   
  • 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);  
  •         }  
  •     }  

  • 参考:http://blog.csdn.net/zzqkillyou/article/details/7388690

    游戏中遇到这样的问题,需要将一组已知的数据打乱,按照以前和现在的做法,总结了以下方法。

    方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :))

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

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

    1. package com.test;  
    2.   
    3. import java.util.Random;  
    4.   
    5.   
    6. public class TestArray {  
    7.  public static int runCount =0;//用于记录方法运算次数  
    8.    
    9.  public int []  m1(int [] arr){  
    10.   Random ran = new Random();  
    11.   int length = arr.length;  
    12.   int [] newArr = new int[length];  
    13.   int count =0;  
    14.   while (true) {  
    15.    runCount ++;  
    16.    int r = ran.nextInt(length)+1;  
    17.    if(!exist(r, newArr)){  
    18.     newArr [count] = r;  
    19.     count++;  
    20.    }  
    21.    if(count==length){  
    22.     break;  
    23.    }  
    24.   }  
    25.   System.out.println("m1 运算次数  = "+runCount);  
    26.   return newArr;  
    27.  }  
    28.    
    29.  public static boolean exist(int a,int [] arr){  
    30.   for (int i = 0; i < arr.length; i++) {  
    31.    if(arr[i] ==a){  
    32.     return true;  
    33.    }  
    34.   }  
    35.   return false;  
    36.  }  


     

    方法二,这种方法是我遇到这个问题就想到的,思路就是:先随机出已知数组的下标值,然后取出这个数放到另一个数组中,再从已知数组中删除这个数。这种方法的运算次数是根据数组长度而定的,缺点是 大部分运算都耗在删除的判断上,主要是因为 数组不像list那样,能删除一个指定位置的值。代码:

    1. //-----------------------------------------------  
    2. public int []  m2(int [] arr){  
    3.  Random ran = new Random();  
    4.  int [] newArr = new int[arr.length];  
    5.  int k = 0;  
    6.  while (arr.length>0) {  
    7.   runCount++;  
    8.   int index = ran.nextInt(arr.length);//随即数组下标  
    9.   newArr[k++] = arr[index];  
    10.   arr = removeElement(arr[index], arr);  
    11.  }  
    12.  System.out.println("m2运算次数  = "+runCount);  
    13.  return newArr;  
    14. }  
    15.   
    16. public int [] removeElement(int ele,int [] arr){  
    17.  int [] arr2 =new int[arr.length-1];  
    18.  int k = 0;  
    19.  for (int i = 0; i < arr.length; i++) {  
    20.   runCount++;  
    21.   if(arr[i]!=ele){  
    22.    arr2[k++] = arr[i];  
    23.   }  
    24.  }  
    25.  return arr2;  
    26. }  


     方法三, 这种方法就很巧妙了,是在c 的代码中看到,翻译成了Java代码,它的巧妙在于:每次从已知数组随机一个数,然后将数组的最后一个值 赋值给前面随机到的数的位置上,然后将长度-1,再从原数组下标-1的数组中随机。 运算次数就是数组长度,这种方法真的很聪明啊,以下是代码:

    1. //-----------------------------------------------  
    2. public int []  m3(int [] arr) {  
    3.  int [] arr2 =new int[arr.length];  
    4.  int count = arr.length;  
    5.  int cbRandCount = 0;// 索引  
    6.  int cbPosition = 0;// 位置  
    7.  int k =0;  
    8.  do {  
    9.   runCount++;  
    10.   Random rand = new Random();  
    11.   int r = count - cbRandCount;  
    12.   cbPosition = rand.nextInt(r);   
    13.   arr2[k++] = arr[cbPosition];  
    14.   cbRandCount++;  
    15.   arr[cbPosition] = arr[r - 1];// 将最后一位数值赋值给已经被使用的cbPosition  
    16.  } while (cbRandCount < count);  
    17.  System.out.println("m3运算次数  = "+runCount);  
    18.  return arr2;  
    19. }  


    测试下代码:

    1. // ----------------------------------------------  
    2.   
    3. public static void main(String[] args) {  
    4.     int[] arr = new int[10];  
    5.     for (int i = 0; i < arr.length; i++) {  
    6.         arr[i] = i + 1;  
    7.     }  
    8.     TestArray t = new TestArray();  
    9.     arr = t.m1(arr);  
    10.     print(arr);  
    11.     arr = t.m2(arr);  
    12.     print(arr);  
    13.     arr = t.m3(arr);  
    14.     print(arr);  
    15. }  
    16.   
    17. public static void print(int[] arr) {  
    18.     for (int i = 0; i < arr.length; i++) {  
    19.         System.out.print(arr[i] + " ");  
    20.     }  
    21.     System.out.println();  
    22.     runCount = 0;  
    23. }  


    结果:

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


    第三种方法还是值得学习的,大家如果有其它好的方法和思路欢迎补充~~


  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI视觉网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值