Generate Random Number with no duplication - java

I want to generate 20 Random numbers in between 1 and 50 with no duplication of numbers and store into an array.
For Example if button click one random number generate like 5 it store in array then if again click on button and one more random number generate if that random number is available in array then generate another and match with array if that random numbers is not there then store in Array.
I want Some Easy code, some code are available in this site but i can't understand those codes. And I am using Java 8 and eclipse Oxygen.
I am using this simple code for generating Random numbers
Random rand=new Random();
i=1;
i=1+rand.nextInt(8);

You can generate random numbers with no duplication by generating an array of increasing numbers and then shuffling it.

You may generate a random number, store it into an array and check every new number against this array. This might slow down your process.
As long as an array with 50 integers will not fill all your memory, you can create int[50] witch integers from 1 to 50 and remove (or create a new array without) the randomly choosen array element. It will not provide a good performance but it seems that this is not really important.

Try somenthing like this:
private List<Integer> numbers = new ArrayList<Integer>();
private Integer generate() {
Random rand = new Random();
int aux;
do {
aux = rand.nextInt(49) + 1; // Random numbers in between 1 and 50
} while (numbers.contains(aux)); // Prevents duplication
return aux;
}
public void btnClick() {
if (numbers.size() < 20) { // Limits to 20 numbers
numbers.add(generate()); // Store in an list
}
}

Related

How can I sort an amount of randomly generated numbers defined by the user in Java?

Hey there Stack Overflow community, so I'm still new to Java but I am trying to learn how to sort. Right now my program creates n amount of random numbers from a range of 1 - 10. Although how I would go about putting these numbers into an array to be sorted, I'm not too sure on. Should i go about doing a bubble sort instead of Arrays.sort?
Here's my code
public static final void main(String aArgs){
//User inputs a number for the amount of random numbers to generate
String UserNumbers = JOptionPane.showInputDialog("How many numbers would you like to generate?");
//The unknown amount of numbers "n" is converted from the "UserNumbers" String to an int
int n = Integer.parseInt(UserNumbers);
//Random number generator generating the amount of numbers as defined by the user
Random randomGenerator = new Random();
for (int idx = 1; idx <= n; ++idx){
int randomInts = randomGenerator.nextInt(10);
//Now to create an array for the random numbers to be put into so they can be sorted
int ArrayToSort[] = new int[n];
ArrayToSort[0] = randomInts;
Arrays.sort(ArrayToSort);
System.out.println(ArrayToSort);
}
}
}
I suspect you are not asking whether to use bubble sort because it's faster/slower then Arrays.sort but instead as Arrays.sort doesn't work for you.
I think this is due to the fact your not putting the random numbers you generated into the array you sort
Instead, try this code:
public static final void main(String args){
//User inputs a number for the amount of random numbers to generate
String userNumbers = JOptionPane.showInputDialog("How many numbers would you like to generate?");
//The unknown amount of numbers "n" is converted from the "userNumbers" String to an int
int n = Integer.parseInt(userNumbers);
//Random number generator generating the amount of numbers as defined by the user
int arrayToSort[] = new int[n];
Random randomGenerator = new Random();
for (int idx = 0; idx < n; ++idx){
arrayToSort[idx] = randomGenerator.nextInt(10);
}
Arrays.sort(arrayToSort);
System.out.println(arrayToSort);
}
The problem with your code is that you are trying to populate an array of size n with random numbers, sort it and then print it, but your code generates in each iteration a random number, allocated an n sized array, put's the random number in slot 0 of the array and sort it, and print it (doint this n times) - which won't get the same effect ofcourse
BTW, Random.nextInt(10) return a random number between 0 and 9, not 1 and 10. to achieve what you want you will need to add 1 to that random value
Arrays.java 's sort method uses quicksort for arrays of primitives and merge sort for arrays of objects. I believe that most of time quicksort is faster than merge sort and costs less memory.
Source: Why does Java's Arrays.sort method use two different sorting algorithms for different types?

Max number from arrays in java

I have created a random program with an array with a lot of values and the frequency of each one, inside it, and I would like the program to find the 5 most frequent numbers is there any way I can do that?
`Here is the code I have already written. 2 random arrays, 2 frequencies, find the 5 numbers withe most frequency out of them:
import java.util.Random;
public class ArrayElementsAsCounters {
public static void main(String[] args){
Random rand = new Random();
int freq[] = new int[46];
int freq2[] = new int[21];
for(int roll=1; roll < 3000000;roll++){
++freq[1+rand.nextInt(45)];
++freq2[1+rand.nextInt(20)];
}
System.out.println("Number\tFrequency");
for(int number1 =1; number1<freq.length;number1++){
System.out.println(number1+"\t"+freq[number1]);
}
System.out.println("Joker\tFrequency");
for(int number2 =1; number2<freq2.length;number2++){
System.out.println(number2+"\t"+freq[number2]);
}
}
}
`
For each value that you have, make them the elements of another array.
This will be the frequency array of the elements.
Now run loop through the original array and each time you encounter an element, add one to its frequency array value.
Then sort the frequency array in descending and starting from the max, print out the first five that are encountered.
Take a look at MultiSets:
https://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multiset.html
You can add all elements into the set and do a sort by count afterwards. Given that the question is broad, I'm just giving guidelines, I'll leave the coding part as an exercise for you to do ;)

Generating Random integers within a range to meet a percentile in java

I am trying to generate random integers within a range to sample a percentile of that range. For example: for range 1 to 100 I would like to select a random sample of 20%. This would result in 20 integers randomly selected for 100.
This is to solve an extremely complex issue and I will post solutions once I get this and a few bugs worked out. I have not used many math packages in java so I appreciate your assistance.
Thanks!
Put all numbers in a arraylist, then shuffle it. Take only the 20 first element of the arraylist:
ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
for(int i = 0; i < 100; i++){
randomNumbers.add((int)(Math.random() * 100 + 1));
}
Collections.shuffle(randomNumbers);
//Then the first 20 elements are your sample
If you want 20 random integers between 1 and one hundred, use Math.random() to generate a value between 0 and 0.999... Then, manipulate this value to fit your range.
int[] random = new int[20];
for(int i =0; i< random.length;i++)
{
random[i] = (int)(Math.random()*100+1);
}
When you multiply Math.random() by 100, you get a value between 0 and 99.999... To this number you add 1, yielding a value between 1.0 and 100.0. Then, I typecasted the number to an integer by using the (int) typecast. This gives a number between 1 and 100 inclusive. Then, store the values into an array.
If you are willing to go with Java 8, you could use some features of lambdas. Presuming that you aren't keeping 20% of petabytes of data, you could do something like this (number is the number of integers in the range to get) it isn't efficient in the slightest, but it works, and is fun if you'd like to do some Java 8. But if this is performance critical, I wouldn't recommend it:
public ArrayList<Integer> sampler(int min, int max, int number){
Random random = new Random();
ArrayList<Integer> generated = new ArrayList<Integer>();
IntStream ints = random.ints(min,max);
Iterator<Integer> it = ints.iterator();
for(int i = 0; i < number; i++){
int k = it.next();
while(generated.contains(k)){
k = it.next();
}
generated.add(k);
}
ints.close();
return generated;
}
If you really need to scale to petabytes of data, you're going to need a solution that doesn't require keeping all your numbers in memory. Even a bit-set, which would compress your numbers to 1 byte per 8 integers, wouldn't fit in memory.
Since you didn't mention the numbers had to be shuffled (just random), you can start counting and randomly decide whether to keep each number or not. Then stream your result to a file or wherever you need it.
Start with this:
long range = 100;
float percentile = 0.20f;
Random rnd = new Random();
for (long i=1; i < range; i++) {
if (rnd.nextFloat() < percentile) {
System.out.println(i);
}
}
You will get about 20 percent of the numbers from 1 to 100, with no duplicates.
As the range goes up, the accuracy will too, so you really wouldn't need any special logic for large data sets.
If an exact number is needed, you would need special logic for smaller data sets, but that's pretty easy to solve using other methods posted here (although I'd still recommend a bit set).

Java how to add a Random Generator that excludes a certain number?

Suppose I wanted to generate random numbers taken from ArrayList:(1,2,3,4,5,6,7,8,9,10)
A Random Generator produces 5.
List gets updated- AL:(1,2,3,4,6,7,8,9,10)
Next Random Number cannot be 5.
I am writing a program that generates random numbers from a arraylist and once it generates the random number the list removes that number and the next random generated digit cannot be that number.
ArrayList<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));
Random randomGenerator = new Random();
int number = 0;
String cont;
do
{
number = randomGenerator.nextInt(numsLeft.size());
numsLeft.remove(number);
System.out.println (number + " continue (y/n)");
cont = (stdin.readLine());
}
while (cont.equalsIgnoreCase("y"));
But the only thing I can do here is lower the size...
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
The easier approach is to simply shuffle your list then use the numbers in the shuffled order:
List<Integer> nums = new ArrayList<Integer>();
for (int i = 1; i < 11; i++)
nums.add(i);
Collections.shuffle(nums);
Now they are in random order, just use them one by one:
for (Integer i : nums) {
// use i
}
You could make an array of the available numbers. Then, the random number generator gives you the position in that array for the number that you want.
Probably a linked list or something would be more efficient, but the concept is the same.
So, with your example, you'd pull 5 the first time. The second time, you'd have this in your list:
1, 2, 3, 4, 6, 7, 8, 9
If your random number was 5 again, the fifth position is 6. Pop the six out, shift 7, 8, 9 over one, and decrement your random number generator to be 1-8 instead of 1-9. continue on.
of course, looking at your code, it looks like that is what you are trying to do already.
What seems to be the issue with your code? What results are you getting?
number = randomGenerator.nextInt(numsLeft.size());
numsLeft.remove(number);
You are now printing the random index that you are generating, not the number that was removed from the list. Is that what you wanted? I think you really meant this:
int index = randomGenerator.nextInt(numsLeft.size());
number = numsLeft.remove(index);
You could also do this using by randomly shuffling the list and then just going through it:
List<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));
// Shuffle the list randomly
Collections.shuffle(numsLeft);
do {
// Remove the first number each time
int number = numsLeft.remove(0);
System.out.println (number + " continue (y/n)");
cont = (stdin.readLine());
} while (cont.equalsIgnoreCase("y"));
Why don't you create a hash map to take care of this. So your hash map can contain something like
Map[(1,1), (2,2), (3,3), ...] or Map[(1,true), (2,true), (3,true), ...]
So if you generate a number, then you can do something like:
String value = map.get(key); or boolean present = map.get(key);
if(value != null) or if(value == present)
map.remove(key), or you can even update the data and instead of removing the key you can update it and add the word removed or a boolean as previously suggested. But this way you can keep track of all the entries and removals in your map for each of the key values which would be your list of numbers.
remove can be pretty expensive operation when list is long. Shuffle is too - especially if you only need a few numbers. Here is another algorithm (it is famous but I can't find the source right now).
put your N (ordered) numbers in a list
Choose a random number m between 0 and N-1
Pick the element at location m. This is your unique random number
SWAP element m with the LAST element in the array
Decrement N by 1
Go to step 2
You "set aside" the numbers you have used in step 4 - but
Unlike shuffle, your initialization is fast
Unlike remove, your remove operation only takes moving one element (instead of, on average, N/2)
Unlike the "pick one and reject if you saw it before", your efficiency of picking a "new" number doesn't decrease as the number of elements picked increases.

Random permutation of integers using a random number generator

This is my homework assignment:
Random r = new Random();
public int get100RandomNumber() {
return 1 + r.nextInt(100);
}
You are given a pre-defined function named getrand100() (above) which
returns an integer which is one random number from 1-100. You can call
this function as many times as you want but beware that this function
is quite resource intensive. You cannot use any other random
generator. You cannot change the definition of getrand100().
Output: Print numbers 1-20 in random order. (Not 20 random numbers)
What I have tried..
public class MyClass {
static Random r = new Random();
static HashSet<Integer>;
public static void main(String args[]) {
myMethod();
System.out.println(s);
}
public static void myMethod() {
boolean b = false;
s = new HashSet<Integer>();
int i = getRand100();
if (i >= 20)
i = i % 20;
int j = 0;
int k, l;
while (s.size() <= 20)
{
System.out.println("occurence no" + ++j);
System.out.println("occurence value" + i);
b = s.add(i);
while (!b) {
k = ++i;
if(k<=20)
b = s.add(k);
if(b==true)
break;
if (!b) {
l = --i;
if(i>=1&&i<=20)
b = s.add(l);
if(b==true)
break;
}
}
}
System.out.println(s);
}
public static int getRand100()
{
return r.nextInt(100) + 1;
}
}
Thanks for any help!
I believe you are asking how to use a random number generator to print out the numbers 1 to 20 in a random order. This is also known as a "random permutation". The Fischer-Yates shuffle is such an algorithm.
However, to implement the algorithm, you first of all need a random number generator that can pick one out of N items with equal probability where N ranges from 2 up to the size of the set to shuffle, while you only have one that can pick one out of 100 items with equal probability. That can easily be obtained by a combination of modulo arithmetic and "rerolling".
Assuming you are allowed to use the ArrayList class, I'd recommend filling a list with the numbers you want (1 to 20 in this case), then randomly pick numbers from the list and remove them. Using getRand100() % theList.size() should be sufficiently random for your cause and you only need to call it 19 times. When only one element is left, there's no need to "randomly" pick it from the list anymore. ;-)
I believe that I've come up with a way to convert any number between 1 and n! (assuming the number of items is known) to a unique permutation of n items.
In essence, this allows for an "immediate" randomization of an entire deck without having to use any shuffling algorithms. For now, it runs in O(n^2) and requires using BigInteger packages (ie. in Java or Javascript), but I'm looking for ways to optimize the runtime (although, honestly 2500 iterations is nothing these days anyway). Regardless, when given at least 226 bits of valid, random data, the function is able to generate a shuffled array of 52 integers in under 10 ms.
The method is similar to that used to convert a decimal number to binary (continually dividing by 2, etc). I'm happy to provide my code upon request; I find it interesting that I haven't come across it before.

Categories