简体   繁体   中英

Shuffling elements in an Array (Java)

I need a shuffle method to shuffle elements of an array which holds objects from another class. At the moment I wrote this code to test with integers first, but it seems to not working perfectly. Most of the elements are being duplicated. Can someone please spot the mistake? And also come up with a more efficient method for this. I am not sure if I can use collections.shuffle because I have further use of my shuffled array later.

  public static void shuffle()
{
  int[] a = new int[52];
  int count = 0;
  int random = 0;
  while (count!=51){
    random = (int)(Math.random() * 52);
    for (int i=0; i <=count; i++){
      if (a[count] != b[random])
        result = true;
    }
    if (result){
      a[count] = b[random];
      count++; 
    }
    b = Arrays.copyOf(a, a.length);
  }
}

First you should not define shuffle() in this way. I would treat b as a parameter and pass it into shuffle() instead of a static field (as your shuffle() is declared as static, your b is also static right? It looks strange to share b between all instances), and result is declared as a local variable.

This part

for (int i=0; i <=count; i++){
    if (a[count] != b[random])
        result = true;
    }

checks whether any one of a[0], a[1] until a[count] is not equal to b[random]. If yes, then assign b[random] to a[count] and increase count by 1. As a[] is not initialized, it is only an array of 0. (a[count] != b[random]) appears to be always true and hence result is true.

Then, for this part,

if (result){
    a[count] = b[random];
      count++; 
    }

say for example random=5, then at the first round of the while loop a[0]=b[5], count=1 (due to count++), and b becomes an array of b[5] and a series of 0. (Due to

b = Arrays.copyOf(a, a.length);

all other elements are replaced by 0.)

Edit: Here I provide a simple method, not thoroughly tested, but should work:

public static int[] shuffle(int[] array) {
    int[] a = new int[array.length];
    //convert int[] to ArrayList<Integer>
    ArrayList<Integer> list = new ArrayList<>();
    for (int i: array)
        list.add(i);
    //now shuffle:
    for (int i=0; i<array.length; i++) {
        int rand = (int)(Math.random()*list.size());
        a[i] = list.remove(rand);
    }
    return a;
}

The array returned is shuffled. Actually I can't say the method "shuffles" the array. It simply creates an empty array, and repeatedly selects an element randomly and put it at the front.

Edit2: This really "shuffles", and this is another approach: does not return a new array. It shuffles the array, 100 times.

public static void shuffle(int[] array) {
    for (int i=0; i<100; i++) {
        int r1 = (int)(Math.random()*array.length);
        int r2 = (int)(Math.random()*array.length);
        int tmp = array[r1];
        array[r1] = array[r2];
        array[r2] = tmp;
    }
}
import java.util.Random;


public class Shuffle {

    public static void main(String[] args) {
        Integer[] a = new Integer[52];
        for (Integer i=0;i<a.length;i++) a[i] = i+1;
        // Let's shuffle
        Random rd = new Random();
        for (Integer i=0;i<a.length;i++){
            Integer changeBy = rd.nextInt(a.length);
            Integer aux=a[i];
            a[i]=a[changeBy];
            a[changeBy] = aux;
        }
        // Now show the shuffled array
        for (Integer i=0;i < a.length; i++) System.out.print(a[i]+",");

    }

}

Hope this small algorithm helps you. As you can see from 2 different runs, it really shuffles your array:

11,1,24,13,28,15,25,48,5,22,12,32,29,42,34,7,33,31,47,18,51,40,8,17,41,20,6,36,21,45,27,52,38,10,30,14,23,19,43,4,50,46,44,3,49,37,35,2,9,26,16,39 3,10,37,26,41,15,28,52,6,24,20,43,33,21,51,32,25,40,50,8,7,5,4,35,13,16,49,17,29,47,12,14,36,39,45,30,2,42,23,38,31,19,27,46,34,11,18,1,22,48,9,44

Why no you HashSet for shuffle?

Elements in java.lang.HashSet are shuffling by their hashcode.

public static void shuffle()
{
    int [] b; // you origin array
    Set<Integer> temp = new HashSet<Integer>();
    for (int i : b) {
        temp.add(i);
    }
    Integer [] a = new Integer[b.length];
    a = temp.toArray(a); // new shuffle array

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM