0

I have an array of size x and I need to go through the list randomly but getting to each element once. What is the most efficient way to do this?

3
  • 1
    possible duplicate of Take n random elements from a List<E>? Commented Sep 14, 2011 at 2:38
  • but getting to each element once -- Does this mean you want to get each element only once ? and not get that element again after shuffling ? Commented Sep 14, 2011 at 5:58
  • @Rakesh, yes I want to get each element only once. Commented Sep 14, 2011 at 13:03

4 Answers 4

7

What you are looking for is shuffle

try this-

// Create a list
List list = new ArrayList();

// Add elements to list

// Shuffle the elements in the list
Collections.shuffle(list);

// Create an array
String[] array = new String[]{"a", "b", "c"};

// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));
Sign up to request clarification or add additional context in comments.

Comments

4

Just shuffle the array and then iterate over it.

Collections.shuffle(Arrays.asList(yourArrayReference));

2 Comments

Collections is not defined. What is collections?
Java collections. Specifically look at Algorithms section.
2

Here is a time and space efficient way to do it.

import java.util.Enumeration;
import java.util.Random;

public class RandomPermuteIterator implements Enumeration<Long> {
    int c = 1013904223, a = 1664525;
    long seed, N, m, next;
    boolean hasNext = true;

    public RandomPermuteIterator(long N) throws Exception {
        if (N <= 0 || N > Math.pow(2, 62)) throw new Exception("Unsupported size: " + N);
        this.N = N;
        m = (long) Math.pow(2, Math.ceil(Math.log(N) / Math.log(2)));
        next = seed = new Random().nextInt((int) Math.min(N, Integer.MAX_VALUE));
    }

    public static void main(String[] args) throws Exception {
        RandomPermuteIterator r = new RandomPermuteIterator(100);
        while (r.hasMoreElements()) System.out.print(r.nextElement() + " ");
    }

    @Override
    public boolean hasMoreElements() {
        return hasNext;
    }

    @Override
    public Long nextElement() {
        next = (a * next + c) % m;
        while (next >= N) next = (a * next + c) % m;
        if (next == seed) hasNext = false;
        return  next;
    }
}

3 Comments

That's very unreadable and though scary code. After 5 minutes I still don't see what is does. But if it really traverses through an array (like the OP asked), then the array must be very well hidden. Also this question was already answered 4 years ago.
It pseudo-randomly enumerates the indices of an array. If you run the above code for instance you will get something like 50 52 3 6 45 40 26 49 92 11 80 2 4 19 86 61 65 44 27 62 5 32 82 9 84 35 38 77 72 7 ... for an array with indices 0..99.
It is a linear congruential generator much like the one used by Java itself. The modulo being sized based on the number of elements in the list means that at most half of the possible values are out of range.
1

You could use a random number generator, which is typically available by default in most object-oriented languages, and use a second array to keep track of what you checked already.

Essentially:

  1. Generate a random number
  2. Search main array for random number
  3. If random number is not in already-checked array...
  4. ...then check the element at main array[random]
  5. Add random number to the end of already-checked array

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.