Random Card Generation

I need to randomly create three cards from an array. I have an array of 52 card names from card1 to card52.

String rank[]=new String[52]; for(int i=0;i<rank.length;i++) { rank[i]= "card"+i; } 

Now I need to select three cards from the array, and this should not be repeated.

Can anybody help me. In fact, I do this, bit cards repel. pls provide me a solution.

Thanks at Advance.

+4
source share
6 answers

Have an array (or even a string) and add to it whenever you select a map. Thus, whenever you select a second or third card, you can choose another one if it is in an array (or row).

Here is one way to do this ... I have not tested if this works.

 String pickedCards = "" int totalPickedCards = 0 boolean continue = true; for(continue) { tempVariable = pickedCard if (pickedCard.contains("/"+tempVariable+"/") == false) { // if you didn't already pick it then pickedCards = pickedCards + "/" + tempVariable + "/"; // save the card you picked - stored in tempVariable ++totalPickedCards } if (totalPickedCards >= 3) { // exit loop if you have 3 cards picked continue = false; } } 
0
source

You can try the Collections.shuffle (List List) method :

 String rank[] = new String[52]; for (int i = 0; i < rank.length; i++) { rank[i] = "card" + i; } List<String> cards = Arrays.asList(rank); Collections.shuffle(cards); List<String> selectedCards = cards.subList(0, 3); 
+15
source

If you convert your array to List , you can use Collections.shuffle() to randomize it. Then, if you just take the first three entries in the list, you will get three random cards without repeats.

 List<String> ranklist = Arrays.asList(rank); Collections.shuffle(ranklist); String rank1 = ranklist.get(0); String rank2 = ranklist.get(1); String rank3 = ranklist.get(2); 
+8
source

Something that could be faster than shuffling the entire array:

 java.util.Random r = new java.util.Random(); int c1 = r.nextInt(52), c2 = r.nextInt(51), c3 = r.nextInt(50); if(c2 >= c1) c2++; if(c3 >= Math.min(c1, c2)) c3++; if(c3 >= Math.max(c1, c2)) c3++; System.out.println("Card 1: " + rank[c1]); System.out.println("Card 2: " + rank[c2]); System.out.println("Card 3: " + rank[c3]); 

In fact, some temporary tests that I used using a generalized (slower) form, this algorithm against Collections.shuffle (screenshot here ) shows that this method is about 3.7 times faster for 3 cards , and in practice faster for Pick up to 24 random cards.

To explain the algorithm to those in doubt:

Probability

We select random numbers - first one of 52. If we need to remove this card, then choose another one that will be one of 51 ... so we are fine with the range of random numbers from the indices we selected.

If we collected and removed from the array, we simply took out the element at index 1, and then took out the element at index 2 and the same for index 3.

What I am doing above adjusts the indices in the same way as outputting elements from an array.

For index two, we have a number, which can be any number from 0 to 50. But let's pretend that we pulled out a card with index 6 ...

This means that instead of a random number spreading in the range from 0 to 50, now we want one spread evenly in the range 0-5 and 7-51. This is another 51 ways. We do this by adding 1 to our second index if it is> = 6. Now we have a number over the correct range with the correct distribution and equal probability if it hits any of the allowed indices.

The same slightly more complex logic applies to the third card: there are no two spots in the deck, so we adjust the third index to cover the available ranges. First, if it is equal to or greater than the first missing position, slide it up. Then, if it is equal to or greater than the second, slide it again. This does not shift the selection to higher values ​​- all we do is avoid indexes that have already been used.

There are no distortions in probabilities.

Efficiency

The comments mentioned that this algorithm and the one that uses Collections.shuffle have the same complexity (i.e. O (n)), and this method is somewhat less readable. The first point is that this algorithm is more complex; those. shuffle the entire array, this is O (n ^ 2). For low n, this algorithm is more efficient. And, I think, the difference in efficiency guarantees the victim a readability. For comparison:

Collections.shuffle

  • choose random number
  • remove item from list
  • insert item into list
  • repeat 51 more times

This method

  • choose random number
  • choose random number
  • choose random number
  • Up to 3 steps

This ignores the transfer from the array to the container required when using the first method. The inevitable conclusion is that this method is much more efficient.

BTW - you can visualize the nature of O (n ^ 2) when you think about choosing 4 cards - which requires up to 6 increments ... 5 cards, up to 10 ... 6 cards, up to 15 ... for n, (n ^ 2 - n) / 2

Summarizing

In this example, I used Math.min and Math.max as an easy way to sort a list of two elements. In the general case (that is, by selecting "n" [1-52 inclusive] non-repeating random cards), we need to sort the list of 52 items. This can be done in the worst case O (n), using insertion sorting while maintaining an ordered list of selected indices. Selecting a new random index is done using

  • Select a new random index using Random.nextInt(52 - selectedIndexListSize)
  • Iterate over a sorted list, with each node, incrementing our selected index if that value is> = node, stopping if it is less
  • output map at the selected index in the array
  • insert our selected index into the sorted list, the moment we stopped

This is O (n) for each choice - but up to 52 samples are given, making it O (n ^ 2).

However, in terms of efficiency, this algorithm is more efficient when m ^ 2 <n, (or, more precisely, whenever m + (m ^ 2-m) / 2 <n), where n is 52 and m is the number selected cards. Thus, this method is more efficient for selecting 7 or less cards (or using a more accurate calc, 9 or less), and therefore, and obviously, is more effective for choosing 3.

+1
source
  Random random = new Random(); List<Integer> randomList = new ArrayList<Integer>(); int randomInt; do { randomInt = random.nextInt(52); if (randomList.contains(new Integer(randomInt))) continue; randomList.add(randomInt); } while (randomList.size() < 3); 

randomList will contain an index of three cards

+1
source

In principle, there are two mathematically feasible methods:

  • As others suggested, shuffle the entire array, and then sequentially select from the very beginning.

  • Choose the first random case. Then select the second randomly. If the second is the same as the first, select random again. those. put the selection in a loop that continues to try until it gets a value that was not previously selected. For the third, you should check the first two, etc. You might want to create a set of flags parallel to the list of cards that are indicated, which were selected, or maybe you can change the map to zero after selecting it, etc.

# 1 is more effective if you intend to use a large percentage of cards. # 2 is more effective if you intend to use a small percentage of cards.

0
source

All Articles