10

I know how to random number using java Random class.

This will random a number between 0-13 13 times;

 public static void main(String[] args) {
    int ctr = 13; 
    int randomNum = 0;
    while(ctr != 0) {
        Random r = new Random();
        randomNum = r.nextInt(13);
        ctr--;
        System.out.println(ctr +": " + randomNum);
    }
 }

Question

-I would like to random a number between 0-13 for 13 times

-If the first random number is e.g(5),then my second random number will random any number from 0-13 again EXCLUDING 5;

If the second random number is e.g(4),then my third random number will random any number from 0-13 again EXCLUDING 5 and 4; etc.. is there a way to do it?

user3820292
  • 310
  • 3
  • 19
  • 1
    possible duplicate of [Creating random numbers with no duplicates](http://stackoverflow.com/questions/4040001/creating-random-numbers-with-no-duplicates) – Brett Holmes Aug 03 '14 at 05:22
  • 1
    Jeff Atwood also has a couple of blog posts relevant to this: [Shuffling](http://blog.codinghorror.com/shuffling/) and [The Danger of Naïveté](http://blog.codinghorror.com/the-danger-of-naivete/). – Daniel Pryden Aug 03 '14 at 06:04

6 Answers6

12

Do this:

  • Create a List of size 13
  • Fill it with numbers 0-12
  • Shuffle the List using the JDK Collections utility method
  • Use the numbers in the shuffled order (by just iterating over the List)

In code:

List<Integer> nums = new ArrayList<Integer>();
for (int i = 0; i < 13; i++)
    nums.add(i);
Collections.shuffle(nums);
for (int randomNum : nums)
    System.out.println(randomNum); // use the random numbers
Bohemian
  • 412,405
  • 93
  • 575
  • 722
8

Question -I would like to random a number between 0-13 for 13 times

I would start with a List and Collections.shuffle(List) and a Random with something like -

Random rand = new Random();
List<Integer> al = new ArrayList<>();
for (int i = 0; i < 14; i++) {
  al.add(i);
}
Collections.shuffle(al, rand);
System.out.println(al);

Or, if using Java 8+, an IntStream.range(int, int) to generate the List. And you could use a forEachOrdered to display (and in either version, you cold use the Collections.shuffle with an implicit random) like

List<Integer> al = IntStream.range(0, 13).boxed().collect(Collectors.toList());
Collections.shuffle(al);
al.stream().forEachOrdered(System.out::println);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
8

I'd fill a list, shuffle it, and then iterate it, guaranteeing a different number each time:

public static void main(String[] args) {
    int ctr = 13; 
    List<Integer> list = new ArrayList<>(ctr);
    for (int i = 0; i < ctr; ++i) {
        list.add(i);
    }
    Collections.shuffle(list);

    for (int i = 0; i < ctr; ++i) {
        System.out.println(ctr + ": " + list.get(i));
    }
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

The answers recommending shuffle show the right way, as it is elegant and fast.

Just for the sake of completeness: you can also slightly alter your code. Add any random number found to an array. Then check the next random number if it is already in the array. If yes, drop the number and get a new one. Do this until the array is filled with 13 numbers.

Like this:

List<Integer> numbers = new ArrayList<Integer>();
Random r = new Random();

while (numbers.size() < 14) {

  randomNum = r.nextInt(13);

  if (!numbers.contains(randomNum)) {
    numbers.add(randomNum);
  }
}
peter_the_oak
  • 3,529
  • 3
  • 23
  • 37
1

you can use Set to avoid having duplicate
Code:

    Set<Integer> set1 = new LinkedHashSet<>();
    int ctr = 13;
    int randomNum = 0;
    while (ctr == 13) {
        Random r = new Random();
        randomNum = r.nextInt(13);
        set1.add(randomNum);
        System.out.print(randomNum + " ");
        if (set1.size() >= 13) {
              ctr = 12;
        }
     }
    System.out.println("");
    set1.forEach(i -> System.out.print(" " + i));

output:

4 11 11 11 5 1 9 12 5 7 5 2 9 10 1 7 10 3 11 8 9 3 12 9 2 6 7 10 12 3 11 1 10 3 6 2 0 
4 11 5 1 9 12 7 2 10 3 8 6 0
Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
  • HashSet iterates in an implementation-defined order, which will destroy the entropy Random gives you in the first place. – Daniel Pryden Aug 03 '14 at 05:29
  • 1
    One issue here is that your answer doesn't include all of the values 0-13. – Elliott Frisch Aug 03 '14 at 05:33
  • @Elliott Frisch Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), so for sure it is gonna incluse 0 and exculde 13 http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int) – Kick Buttowski Aug 03 '14 at 05:37
  • 1
    What you're doing is adding 13 random numbers to a set. If there's a duplicate, you'll end up with just 12 numbers since the duplicate will be dropped. Also, you're then iterating over the set, which for all we know (and are guaranteed) might iterate them in numerical order, which defeats the purpose. – Avner Shahar-Kashtan Aug 03 '14 at 05:40
  • thank you for your resposne but the OP did not want the duplicate. am I right? – Kick Buttowski Aug 03 '14 at 05:42
  • Should I use LinkedHashSet? Is it better right now? – Kick Buttowski Aug 03 '14 at 05:43
  • @KickButtowski: LinkedHashSet is better, now the order is actually random (or at least *as random* as your input entropy allows). But collisions will still cause the set to not hold every element. You need to keep iterating until the set has the size you want. – Daniel Pryden Aug 03 '14 at 05:51
  • @DanielPryden could you please edit my answer or email it to me? – Kick Buttowski Aug 03 '14 at 05:52
  • @KickButtowski: I'm on a tablet at the moment, so typing code is annoyingly tedious. And there are plenty of examples of this kind of thing on the linked duplicate question, so there's no point in rehashing those here (pardon the pun). If you're having trouble understanding the answers on the other question, you can also always ask a new question for more clarification. – Daniel Pryden Aug 03 '14 at 05:59
  • That's how I read the OP's requirement about "excluding 5" in the question. – Daniel Pryden Aug 03 '14 at 06:07
  • @DanielPryden how do you like my answer now? I have 13 onsorted elements which are random. The OP said 5 and 4 as examples ... – Kick Buttowski Aug 03 '14 at 06:15
  • You're still creating the `Random` instance in a loop, though. If you want a general review of your code, there's also codereview.stackexchange.com you could ask. The comments are getting long here, so you should open a new question if you want further assistance. – Daniel Pryden Aug 03 '14 at 06:21
1
ArrayList<Integer> nums = new ArrayList<Integer>();
Random generator = new Random();
for (int i = 0; i < 14; i++) {
    nums.add(i);
}
for (int i = 0; i < 14; i++) {
    int size = nums.size();
    int chosen = generator.nextInt(size);
    System.out.println(nums.get(chosen) + " ");
    nums.remove(chosen);
}
Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Chad
  • 159
  • 1
  • 3
  • 15