3

If there is a for loop like

for ( int i = 0; i <= 10; i++ )
{
   //block of code
}

What I want to achieve is, after first iteration i value need not to be 1, it can be anything from 1 to 10, i should not be 0 again and similarly for other iterations.

Code Enthusiastic
  • 2,687
  • 5
  • 21
  • 36

3 Answers3

7

Simple algorithm:

  • create an array containing numbers from 0 to 10
  • shuffle
  • iterate over that array and retrieve the corresponding index in the initial collection

In Java:

public static void main(String[] args) throws Exception {
    List<Integer> random = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    Collections.shuffle(random);

    List<String> someList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k");

    for (int i : random) {
        System.out.print(someList.get(i));
    }
}

outputs:

ihfejkcadbg

EDIT

Now that I reread it, you could also simply shuffle the initial collection and loop:

public static void main(String[] args) throws Exception {
    List<String> someList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j");

    //make a copy if you want the initial collection intact
    List<String> random = new ArrayList<> (someList);
    Collections.shuffle(random);

    for (String s : random) {
        System.out.print(s);
    }
}
assylias
  • 297,541
  • 71
  • 621
  • 741
6

Yes, you can do that: first, create a random permutation of numbers 0..N-1, and then iterate like this:

int[] randomPerm = ... // One simple way is to use Fisher-Yates shuffle
for (int i in randomPerm) {
    ...
}

Link to Fisher-Yates shuffle.

Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
2

The "shuffle" approach is probably the easiest, but pulling them out in random order can work too; the main problem with this is that RemoveAt is relatively expensive. Shuffling would be cheaper. Included for completeness:

var list = new List<int>(Enumerable.Range(0, 10));
var rand = new Random();
while (list.Count > 0) {
    int idx = rand.Next(list.Count);
    Console.WriteLine(list[idx]);
    list.RemoveAt(idx);
}
Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • this one answers the question if it is 0 through 10 ,what if Enumerable range start seed is from a non-zero number for instance like this Enumerabl.Range(5,10) – Sankara Jan 12 '13 at 16:04
  • @101010 you'd add the offset in about 2 lines of code; not a biggie – Marc Gravell Jan 12 '13 at 20:31