This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 11 months ago.
With the below code if we try to generate random numbers from 1 to 10, I some times get duplicate values.
Below code should generate 5 unique values for random numbers between 1 to 10.
When I print the array it happens uniqueness is not guaranteed. Output was 2,1,9,10,2.
2 was repeated in this case.
Random random = new Random(System.currentTimeMillis());
random.setSeed(System.currentTimeMillis());
int[] myUniqueValues = new int[5];
for (int i = 0; i < 5; i++) {
myUniqueValues[i] = random.nextInt(10) + 1;
}
return myUniqueValues;
One way of doing this would be to create a list and pick randoms from it:
Random r = new Random();
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0: i<10; i++){
list.add(i);
}
private int getUniqueRandom(){
int index = r.nextInt(list.size());
int number = list.get(index);
list.remove(index); // Check that it removes the Index not the value from list
return number;
}
Another way if you have a lot of numbers and dont want to store them in memory
Random r = new Random();
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<5; i++){
do{
int number = r.nextInt(10);
}while(!list.contains(number))
list.add(number);
}
The way with Set as suggested by steven7mwesigwa
This works because Sets can only contain unique values
Random r = new Random();
HashSet<Integer> list = new HashSet<Integer>();
while (list.size() < 5) {
list.add(r.nextInt(10));
}
A one liner from https://stackoverflow.com/a/31656679/11355399
int[] array = ThreadLocalRandom.current().ints(0, 10).distinct().limit(5).toArray();
We can use Set Collection here to remove duplicates inside loop itself. Set has method called contains which will check weather output of random function is already present in our result set or not. if it is present we can skip that iteration. if not we can random to our result set. please check below snippet.
Random random = new Random(System.currentTimeMillis());
random.setSeed(System.currentTimeMillis());
Set<Integer> myUniqueValues2 = new HashSet<>();
int k=0;
while(k<5) {
int test = random.nextInt(10) + 1;
if(!myUniqueValues2.contains(test)) {
myUniqueValues2.add(test);
k++;
}
}
for(int i: myUniqueValues2)
System.out.println(i+" ");
Related
This question already has answers here:
How can I prevent the overlapping random numbers
(8 answers)
Closed 2 years ago.
I need to get the numbers 0-11 in a random order and make sure each number is only gotten once. It is still sending same numbers into my Line2 class though. How do I make sure that the int variable lineChoice is completely different every time?
My problem is the if/else is not properly making sure that I don't send an already selected lineChoice to my Line2 class.
for(int i = 0; i < 12; i++){
//get a random line choice 0-11
lineChoice = (int)(Math.random() * 11); //0-11;
//if that number was already chosen
//get a new random number and add it to the array
if(randomNumbers.contains(lineChoice)){
lineChoice = (int)(Math.random() * 11); //0-11;
randomNumbers.add(lineChoice);
}else{
//if not already in array, add to array
randomNumbers.add(lineChoice);
}
//make a Line based on the random lineChoice number
line = new Line2(lineChoice);
//add the line to the string poem
poem += "\n" + line + "\n\n\n";
}
You can create a List of Int from 1 to 11, and then randomize it.
List<Integer> ints = IntStream.range(1,12).boxed().collect(Collectors.toList());
Collections.shuffle(ints);
System.out.println(ints);
Here is the recommended way of doing it.
int [] nums = {0,1,2,3,4,5,6,7,8,9,10,11};
for (int i = nums.length-1; i >= 0; i--) {
int s = (int)(Math.random()*(i+1));
System.out.println(nums[s]); // here is where you get your number
nums[s] = nums[i];
}
or if you just want to shuffle the array.
for (int i = nums.length-1; i >= 0; i--) {
int s = (int)(Math.random()*(i+1));
int t = nums[s];
nums[s] = nums[i];
nums[i] = t;
}
You need an array to do so,
Follow the following code, you just need to generate 11 (out of 12) random numbers in total. The last number will be selected automatically.
int[] rn = new int[12];
for(int i=0; i<12; i++) rn[i]=i; // 0 to 11
Random rNumber = new Random();
int t, z;
for(int i=11; i>0; i--) {
z = rNumber.nextInt(i+1);
t = rn[i];
rn[i] = rn[z];
rn[z] = t;
}
System.out.println(Arrays.toString(rn));
This question already has answers here:
Java Array of unique randomly generated integers
(10 answers)
Closed 5 years ago.
i want to create an array of 10000 unique random elements. Till now i only figure out how to create random integers and fill an array and finding the doubles and deleted them. But this decrease the size of the array which i dont want it.
So the question is how i can fill an array with unique integers as elements without decreasing the size of the array.
You could use this code. Usage of Set will eliminate duplicates and you are fetching random numbers until you get 10000 different random integers.
Set<Integer> numbers = new HashSet<>();
Random r = new Random();
while (numbers.size() < 10000) {
numbers.add(r.nextInt(100000));
}
Integer[] a = new Integer[numbers.size()];
a = numbers.toArray(a);
I found this great solution:
This solution doesn't need any Collection class.
public static int[] createRandomNumbers(int howMany) {
int n = howMany + 1;
int a[] = new int[n];
for (int i = 0; i < n; i++) {
a[i] = i;
}
int [] result = new int[n];
int x = n;
SecureRandom rd = new SecureRandom();
for (int i = 0; i < n; i++) {
int k = rd.nextInt(x);
result[i] = a[k];
a[k] = a[x-1];
x--;
}
return result;
}
System.out.println(Arrays.toString(createRandomNumbers(10000)));
Reference: Best way to create a list of unique random numbers in Java
Hope it helps
Try this logic:
USE AN ARRAYLIST ENTIRELY, THEN CONVERT TO AN ARRAY AT THE END OF THE ENTIRE OPERATION.
Declare an arraylist
For every random number generated, check if the number already exists in the arraylist (using the .contains() method). If it does, repeat the process, else, move to the next number.
Code example:
Arraylist<Integer> arr = new Arraylist<>();
arr.add(generate()); //I included this line so that the arraylist won't be empty
//Note that the method *generate()* generates a new random number
for(int i = 0; i < 9999; i++){
int next = generate(); //the method that generates your number
if(arr.contains(next)){
i--; //The entire operation will be repeated for this index.
}
else{
arr.add(next); //Add the number to the arraylist
}
}
int[] finalArray = arr.toArray(); //Your final resultant array!
I hope this helps.. Merry coding!
You can use Set. This Collection that contains no duplicate elements.
Documentation https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
Set<Integer> numbers = new HashSet();
do {
numbers.add(ThreadLocalRandom.current().nextInt());
} while(numbers.size() < 10000);
int[] drawNumbers = new int[10];//Array With 10 Random Numbers USED for DRAWN NUMBERS
String x = "Drawn Numbers: ";
List<Ticket> ticketWon ;
do{
//GENERATING 10 Random Numbers
for (int i = 0; i <= drawNumbers.length -1 ; i++) {
Random r = new Random();
drawNumbers[i] = r.nextInt(99) + 1;
x += drawNumbers[i] + " ";
}
}
I'm trying to generate 10 random numbers that must be random generated and Unique. My problem is that with Random r = new Random() there are times that replicated numbers are shown. How can i generate 10 random numbers from range 1 to 99 without replications?
Problem is for a Lottery System
I would like to use Collection.Shuffle but I'm not that sure how it should be implemented.
Here is an alternative way to achieve your desired result. We populate a list with values 1 to 99. Then we shuffle the list and grab the first 10 values:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<100; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
for (int i=0; i<10; i++) {
System.out.println(list.get(i));
}
}
You won't have to import/directly deal with Random, which is a plus. However, as pointed out by #Voicu (in the comments), shuffle does indeed utilize random:
public static void shuffle(List<?> list) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
}
private static Random r;
You can broadly think of this problem as having a deck of cards numbered from 1 to 99, and you want to pick 10 of those cards. The solution would be to, programmatically, create that deck and then randomly select from that deck and remove from the deck.
We can model the deck as a List of Integers and populate that List with entries from 1 to 99 with something like this:
List<Integer> deck = new ArrayList<Integer>();
for( int i=1; i<=99; i++ ){
deck.add( i );
}
We then need to pick a random card between the 0th card (lists are numbered starting at 0) and the number of elements in the list:
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
And repeat that 10 times, doing something with the "card" (say, putting it into an array, or another list, or whatever:
int drawNumbers = new int[10];
for( int co=0; co<10; co++ ){
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
drawNumbers[co] = card;
}
Use Set<Integer>.
Set<Integer> set = new HashSet<Integer>();
int[] drawNumbers = new int[10];
Random r = new Random();
for(int i=0; i<10; i++)
{
drawNumbers[i] = r.nextInt(99) + 1;
while(set.contains(drawNumbers[i]))
drawNumbers[i] = r.nextInt(99) + 1;
set.add(drawNumbers[i]);
}
I'd generate random numbers and save them to a Set until I get 10 numbers. Then create a list from it, shuffle it, and then take numbers from it.
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
Set<Integer> randoms = new HashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
// Now shuffle them:
List<Integer> shuffledRandom = new ArrayList<>(randoms);
Collections.shuffle(shuffledRandom);
EDIT:
As #MarkPeters noted in the comments, using a LinkedHashSet would eliminate the need to shuffle:
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
LinkedHashSet<Integer> randoms = new LinkedHashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
It would be easier to use a list so you could check if it already contains the number and re-generate if it does.
List<Integer> drawNumbers = new ArrayList<Integer>();
Random r = new Random();
int newNumber = -1;
do
{
newNumber = r.nextInt(99) + 1;
} while(drawNumbers.contains(newNumber); //Make sure the number is not already in the list.
Then put this in a loop to repeat 10 times.
I've created an ArrayList for integers which I would like to fill with 200 numbers. Each number can be within a range between 0 and 1023.
Therefore I've written this code:
Random rand = new Random();
ArrayList<Integer> values = new ArrayList<Integer>();
int START_AMOUNT = 200;
for(int i = 0; i < START_AMOUNT;
values.add(rand.nextInt(1024));
}
As You might see, the for-loop will add 200 random numbers to the "values" ArrayList, from 0 to 1023. Now my problem is that I want the Array to have only unique numbers. How can I tell the Random class not to generate any numbers that already are existent in the ArrayList?
What I'd do is creating an array of 1023 int composed by 1,2,3,...,1023. Then you shuffle it, and you take only the 200 first terms :
List<Integer> ints = new ArrayList<Integer>();
for(int i = 1; i <= 1023; i++)
{
ints.add(i);
}
Collections.shuffle(ints);
EDIT as suggested by #Bohemian♦
List<Integer> result = ints.subList(0,200);
A Set is a Collection that cannot contain duplicate elements.
It models the mathematical set abstraction.
The Set interface contains only methods inherited from Collection
and adds the restriction that duplicate elements are prohibited.
And therefore,
public boolean add(E e)
Adds the specified element to this set if it is not already present.
[...]
If this set already contains the element,
the call leaves the set unchanged and returns false.
As such, what I'd do is use a Set, then add those to the list:
List<Integer> values = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
while(set.size() < 200)
{
set.add(rand.nextInt(1024));
}
values.addAll(set);
Use a Set:
Random rand = new Random();
Set<Integer> values = new HashSet<Integer>();
final int START_AMOUNT = 200;
while(values.size() < START_AMOUNT) {
values.add(rand.nextInt(1024));
}
List<Integer> uniqueList = new ArrayList<Integer>(values);
System.out.println(uniqueList);
You could also check if the ArrayList contains the given random number everytime you want to add one.
Random rand = new Random();
Integer r;
ArrayList<Integer> values = new ArrayList<Integer>();
int START_AMOUNT = 200;
for(int i = 0; i < START_AMOUNT; i++) {
r = rand.nextInt(1024);
If !values.contains(r) {
values.add(r);
} else {
i--;
}
}
Although i think Kabulan0lak's answer would be more performant if that is important.
I do have the following code for taking random int numbers
for (int i=1;i<=5;i++) {
int rand= new Random().nextInt(10);
Log.d("Ramdom number", String.valueOf(rand));
}
The problem is that I dont want random numbers to be repeated, mean when I run this code it gives to me 5 numbers but two of them at least repeats. Any advice?
For a small range of numbers to choose from, this should do the trick:
ArrayList<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < 20; ++i) {
numbers.add(i);
}
Collections.shuffle(numbers);
for (int i = 0; i < 5; ++i) {
Log.d("Random number", numbers.get(i).toString());
}
The problem is that you are creating a Random object within the loop. If the loop is a 'tight', as in this case, the Random object will be seeded with the same value. Moving the Random object initialization outside the loop should do the trick.
Random r = new Random();
for (int i=1;i<=5;i++) {
int rand= r.nextInt(10)
Log.d("Ramdom number", String.valueOf(rand));
}
EDIT:
This should work (at least it did for me)
public static Integer[] getRangedInt(int maxRange, int numCount)
{
if (maxRange < numCount)
{
throw new Exception("maxRange cannot be smaller than numCount");
}
Set<Integer set = new HashSet<Integer>();
Random r = new Random();
while (Set.size() < numCount)
{
int random = r.nextInt(maxRange);
while (!set.add(random))
{
random = r.nextInt(maxRange);
}
}
return set.toArray(new Integer[set.size()]);
}
final int maxnumbers = 5;
final int maxvalue = 10;
final Random generator = new Random();
Set<Integer> numbers = new HashSet<Integer>();
while(numbers.size() < maxnumbers){
numbers.add(random.nextInt(maxvalue));
}
After this loop you should have maxnumber non-repeating random numbers between 0 and maxvalue in the set numbers. You have to watch out so you don't get too many iterations when using this method, i.e. generating 9999 non-repeating numbers out of 10000 would probably take a long time.
Another more scalable version would be to have a list of numbers:
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<maxvalue; i++){ numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> randomnums = numbers.subList(0, maxnumbers);
I think you need a SET of random numbers. This hint should suffice.
If not, then please comment.
You can maintain one list of generated numbers
boolean flag=false;
Vector<int> vec = new Vector<int>();
for (int i=1;i<=5;i++) {
flag=false;
int rand= r.nextInt(10);
for(int j=0;j<vec.size();j++)
{
if(vec.get(j)==rand)
{
flag=true;
break;
}
}
if(flag)
{
continue;
}
else
{
Log.d("Ramdom number", String.valueOf(rand));
vec.add(rand);
}
}
You can maintain a vector of generated numbers and check
Is that number already generated then generate new one
else display this number
So what you're looking for isn't a list of random numbers, it's a list of 30 numbers randomly ordered.
One way is to generate a list of all possible values, then order them randomly, then peel them from the front of the list as needed. Here's some pseudocode:
for(int i=1; i<=30; i++) {
double r = rand();
while (null != aTreeSet.get(r)) r = rand();
aTreeSet.put(r, i);
}
where rand() returns some random value (not the 1-30 you seek, that's i) perhaps between 0 and 1 and aTreeSet is what you think.
The loop prevents sadness in the unlikely event of a dup being returned by rand().
To use this, pull values from aTreeSet in sorted order.
edit - Gross solution
Another way is to generate the 1-30 value, and if it isn't already in a "I have seen this" Set, add it and return the value. if it is there, generate a new random number. Repeat until an unused number is discovered. This performs poorly, relatively speaking, for the last few values. For 30 values on modern processors, it will get done in milliseconds, of course. If your max value was 1,000 instead of 30, I'd start getting concerned.
What you want is a random combination, use a Hash table to avoid repetitions
From the top of my head the code should be something like:
Ramdom r = new Random();
Hashtable<Integer, Integer> h = new Hashtable<Integer, Integer>();
while( h.keys().size() < 5 ) {
int i = r.nextInt(10);
h.put(i,i);
}
Integer[] k = (Integer[]) h.keySet().toArray();
The line
h.put(i,i);
just overrides the value if it is repeated, so only different drawn numbers will have entries in the hash table.
You can save your generated numbers in a Set and use the random number only if it is not in the set
Random r = new Random();
Set<Integer> generatedNumbers = new HashSet<Integer>();
for(int i = 1;i<=5;i++) {
int rand = r.nextInt(10)
if (!generatedNumbers.contains(rand)) {
Log.d("Ramdom number", String.valueOf(rand));
generatedNumbers.add(rand);
}
}