简体   繁体   中英

Generate random numbers from 0 to 7 with every number appearing 2 times in java ADT

I need to generate random numbers from 0 to 7 with every number appearing 2 times. The end result should have every number appearing 2 times, in random order. An example would be:

MyArray = [3, 6, 0, 5, 2, 2, 6, 7, 5, 4, 7, 1, 3, 1, 0, 4]

This is what I tried to do. The code works alone but not in an ADT environnement (in an adapter class that is visited 16 times, but only 14 when I use this code).

ArrayList<Integer> nombres = new ArrayList<Integer>();
private int getRandomNumber() {

    Random rand = new Random();
    int temp;

    while(true){
        temp = rand.nextInt(8);

        if (nombres.size()==0) {
            nombres.add(temp);
            return temp;
        }

        if (nombres.contains(temp)){
            if (nombres.indexOf(temp) == nombres.lastIndexOf(temp)){
                nombres.add(temp);
                return temp;
            }
        }

        if (!nombres.contains(temp)){
            nombres.add(temp);
            return temp;
        }



    }

}

Any other, easier solutions? (I have tried to put everything in a single if, same result).

A straightforward way is to do it with Collections.shuffle() .

Pseudocode:

for(0 to 7)
   myArrayList.add(num);
   myArrayList.add(num);
Collections.shuffle(myArrayList);

// Convert to array if necessary

A much simpler way is to populate the results first, then serve them out:

List<Integer> nombres = new ArrayList<Integer>();
int index;

private int getRandomNumber() {
    if (nombres.isEmpty()) {
        for (int i = 0; i < 8; i++) {
            nombres.add(i);
            nombres.add(i);
        }
        Collections.shuffle(nombres);
    }
    if (index >= nombres.size())
        throw new IllegalStateException();
    return nombres.get(index++);
}

Adding all the numbers and then using Collections.shuffle would probably be easiest.

List<Integer> generateRandomArray(int max) {
    List<Integer> result = new ArrayList<Integer>();
    for(int i = 0; i <= max; i++) {
        result.add(i);
        result.add(i);
    }
    Collections.shuffle(result);
    return result;
}

Using unique numbers this way is inefficient in general.

A better way to do this is first generating the array of integers and then using swap operations to generate a random list:

int n = 8;//maximum bound (exclusive)
int s = 2*n;
Random rand = new Random();
int[] result = new int[s];
for(int i = 0, j = 0; i < n; i++) {
    result[j++] = i;
    result[j++] = i;
}
for(int i = 0; i < s; i++) {
    int j = i + rand.nextInt(s-i);
    int temp = result[i];
    result[i] = result[j];
    result[j] = temp;
}

Or its equivalent for ArrayList<Integer> :

int n = 8;//maximum bound (exclusive)
int s = 2*n;
Random rand = new Random();
ArrayList<Integer> result = new ArrayList<Integer>();
for(int i = 0, j = 0; i < n; i++) {
    result.add(i);
    result.add(i);
}
for(int i = 0; i < s; i++) {
    int j = i + rand.nextInt(s-i);
    int temp = result.get(i);
    result.set(i,result[j]);
    result.set(j,temp);
}

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