• import
•   
• public class
• public static void
• new
• for (int i = 0; i < 10; i++)  
• new
• "打乱前:");  
•         System.out.println(list);  
•   
• for (int i = 0; i < 5; i++) {  
• "第" + i + "次打乱:");  
•             Collections.shuffle(list);  
•             System.out.println(list);  
•         }  
•     }  
• }

  • 参考:


    游戏中遇到这样的问题,需要将一组已知的数据打乱,按照以前和现在的做法,总结了以下方法。
    方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :))
    从已知数组中随机一个数,然后加入到另一个数组中,在加入之前,先检查是否已经加入过。
    这种方法有很大运气成分,且数据越大,效率越低,超过一定数目,则程序几乎无法执行,会一直卡在那里,代码:

1. package
2.   
3. import
4.   
5.   
6. public class
7. public static int runCount =0;//用于记录方法运算次数
8.    
9. public int []  m1(int
10. new
11. int
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. "m1 运算次数  = "+runCount);  
26. return
27.  }  
28.    
29. public static boolean exist(int a,int
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
3. new
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. "m2运算次数  = "+runCount);  
13. return
14. }  
15.   
16. public int [] removeElement(int ele,int
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
26. }

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

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

测试下代码:

1. // ----------------------------------------------
2.   
3. public static void
4. int[] arr = new int[10];  
5. for (int i = 0; i < arr.length; i++) {  
6. 1;  
7.     }  
8. new
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. " ");  
20.     }  
21.     System.out.println();  
22. 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

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



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

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

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

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

1. package
2.   
3. import
4.   
5.   
6. public class
7. public static int runCount =0;//用于记录方法运算次数
8.    
9. public int []  m1(int
10. new
11. int
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. "m1 运算次数  = "+runCount);  
26. return
27.  }  
28.    
29. public static boolean exist(int a,int
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
    3. new
    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. "m2运算次数  = "+runCount);  
    13. return
    14. }  
    15.   
    16. public int [] removeElement(int ele,int
    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
    26. }



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





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



    测试下代码:



    1. // ----------------------------------------------
    2.   
    3. public static void
    4. int[] arr = new int[10];  
    5. for (int i = 0; i < arr.length; i++) {  
    6. 1;  
    7.     }  
    8. new
    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. " ");  
    20.     }  
    21.     System.out.println();  
    22. 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



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