Random number generator without replacement? - java

I have tried to program a random number generator that doesn't generate the same random number more than once. But I am unable to and can't figure out why. My code is like this at the moment:
public void printNS(){
System.out.print("Numeros Numeros: ");
for(int i=0; i < 5 ; i++){
System.out.print( (int)(Math.random()*50) + ",");
}
System.out.print("; Numeros Stars: ");
for(int i=0; i < 2 ; i++){
System.out.print( (int)(Math.random()*12)+ ",");
}
}

in java 8 you can do the following
int[] rand = new Random().ints(start, end).distinct().limit(number).toArray();
for more details/options see the doc
And before java 8 you can use a Set. Generate the random numbers until your set size is less than the desired number of random numbers

So you want k distinct random numbers from 0 to n (with k < n).
Two possible approaches:
Pick k random numbers, as you already did, and store them in a data structure. Everytime you pick a number, check if it is already contained in the structure: if it is, keep picking until you have a "new" random number. It is a simple enough approach but the loop could potentially block your application. I suggest to use a Set since it stores distinct elements by definition
Set<Integer> set = new LinkedHashSet<>(); // unordered
while (set.size() < k){
set.add((int)(Math.random()*n));
}
System.out.println(set);
Create a List and initialize it with every number between 0 and n. Then shuffle it. First k elements of the list are the numbers you want.
List<Integer> list = new ArrayList<>(n);
for (int i = 0; i < n; i++){
list.add(i);
}
Collections.shuffle(list);
list.subList(0, k).clear();
System.out.println(list);
I would suggest the second approach as it is more clean, I don't know your efficiency requirements though.

Here:
private printStars(int loops, int factor) {
for(int i=0; i < loops ; i++){
System.out.print( (int)(Math.random()*factor) + ",");
}
And now:
public void printNS(){
System.out.print("Numeros Numeros: ");
printStars(5, 50);
System.out.print("; Numeros Stars: ");
printStars(2, 12);
Hope that helps. The key point is: when you have repeating code, look at those elements that are "identical"; and then move them into another method!

Related

How do I get the code to print random numbers in all the elements of the 2d array?

I got the 2d array to print but with all zero's and the only random number comes up on the bottom right corner
How do I get the code to print random numbers in all the elements of the 2d array?
Here is my code:
public static void main(String[] args) {
int columns = 8;
int rows = 4;
int rLow = 2;
int rHigh = 9;
printRandos(columns, rows, rLow, rHigh);
}
public static void printRandos(int clmn, int rws, int rlow, int rhigh) {
Random rando = new Random();
int randoNum = rlow + rando.nextInt(rhigh);
int[][] randoArray = new int[rws][clmn];
for (int i = 0; i < rws; i++) {
for (int k = 0; k < clmn; k++) {
randoArray[rws - 1][clmn - 1] = randoNum;
System.out.print(randoArray[i][k] + " ");
}
System.out.print("\n");
}
}
for (int i = 0; i < rws; i++)
{
for (int k = 0; k < clmn; k++)
{
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
}
System.out.print("\n");
}
your mistake inside the inner for loop of the printRandos method. Firstly your random number is outside the loop so your array elements were receiving the same number all the time. Another mistake is that you are assigning the value to the same array element all the time i.e rws-1 and clmn-1 .
inside your inner loop replace it with this:
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
Your bug is in this line:
randoArray[rws-1][clmn-1] = randoNum;
This stores your random number into randoArray[rws-1][clmn-1] each time, which as you noticed, is the bottom right corner. rws is always 4, and clmn is always 8. So you store the same number there 32 times, which gives the same result as storing it only once.
In the following line you are correctly printing the number from the current array location:
System.out.print(randoArray[i][k]+" ");
An int array comes initialized with all zeroes, and since except for the last corner you have not filled anything into your array, 0 is printed.
Also if you want different random numbers in all the cells, you would need to call rando.nextInt() inside your innermost for loop.
Unless you need this 2-D array for some purpose (which doesn't show from the minimal example code that you have posted), you do not need it for printing a matrix of random numbers, i.e., you may just print the numbers form within your loop without putting them into the array first.
Finally if rhigh should be the highest possible random number in the array, you should use rando.nextInt(rhigh - rlow + 1). With rlow equal to 2 and rhigh equal to 9 this will give numbers in the range from 0 inclusive to 9 - 2 + 1 = 8 exclusive, which means that after adding to rlow = 2 you will get a number in the range from 2 to 10 exclusive, in other words, to 9 inclusive.
I am on purpose leaving to yourself to fix your code based on my comments. I believe your learning will benefit more from working it out yourself.
Your assign the array value outside the array length
int[][] randoArray = new int[rws][clmn];
randoArray[rws][clmn] = randoNum;
Here randoArray[rws] is out of bounds.

Modification of Bubblesort program with user input

I have created a program previously using the BubbleSort method that works to sort numbers in a list that already exists, however, I am having difficulty with trying to manipulate this program in order to allow a user to input the list of numbers to be sorted instead. So far I have:
import java.util.Scanner;
public class MedianValue {
public static void main(String[] args) {
//use scanner to input list of numbers to sort
Scanner scan = new Scanner(System.in);
int[] numbers = new int[] {scan.nextInt()};
//nested for loop
//outer loop just iterating
//inner loop going through and flipping
//checking if out of order (if statement)
int counter = 0;
//outer loop: keep doing this until it's sorted
for(int i = 0; i < numbers.length - 1; i = i + 1)
//put in a inner loop number.length times minus one because we don't want to swap the last element
for(counter = 0; counter < numbers.length - 1; counter = counter + 1)
{
if (numbers [counter] > numbers [counter + 1])
{
int temporary = numbers [counter];
numbers [counter] = numbers [counter + 1];
numbers [counter + 1] = temporary;
}
}
for(int i =0; i < numbers.length; i = i + 1)
{
System.out.print(numbers[i] + " ");
}
}
}
But, in this program, instead of sorting the inputted numbers, the program simply prints the first number that is inputted by the user. I am not sure if I need to move where my scanner function is placed, or add on to it within the loop for it to sort all of the numbers as I want it to do. I am lost on where to change the program if that is the case.
That's because int[] numbers = new int[] {scan.nextInt()}; is a single assigment. scan read a single input and assign to number[0].
You actually need to modify your code for scan to read n numbers and store in n-sized numbers.
something like.
int[] numbers = new int[scan.nextInt()];
for( int i = 0; i < numbers.length; i++)
numbers[i] = scan.nextInt();
The code int[] numbers = new int[] {scan.nextInt()}; will always create an array (not a List) of size 1.
Usually in these kinds of assignments you get n + 1 numbers, for example 5 3 6 2 4 1 would mean "I'm going to give you five numbers. Oh here they are: 3 6 2 4 and 1!"
You probably want something like int[] numbers = new int[scan.nextInt()]; - then loop from 0 to numbers.length to fill the array.

How can I display chosen array contents to the user in java?

I have created a random number generator and I also have an array of 30 items, however I require it to use the numbers generated to get the positions of the items in the array and display it. Sorry if I don't make much sense, I'm still trying to understand it myself!
Here's my random number generator code!
public void passRndNum() throws IOException
ArrayList <Integer> aNumber = new ArrayList <Integer>();
for (int i = 0; i < 29; i++)
{
aNumber.add(new Integer(i));
}
Collections.shuffle(aNumber);
for (int i = 0;i < 2 ; i++)
{
aPlayer[i].receiveCard(aNumber.get(i));
}
}
Is it possible to create random number between 0 and 29
Yes.
Random rnd = new Random();
rnd.nextInt(30);
to represent a counter
Yes.
int counter = rnd.nextInt(30);
of an array of 30 items
Yes, you can have an array of 30 items. Lets call it ... myArray.
and then call that counter and item to the display?
Yes.
System.out.println(counter + ": " + myArray[counter]);

Create an array of UNIQUE 5-digit random numbers in Java?

I have the following code generating 5-digit random numbers and adding them to an ArrayList. These numbers however must be unique ids.
for(int i = 0; i < myArr.length; i++) {
int id = (int) (Math.round(Math.random() * 89999) + 10000);
idArr.add(id);
}
I'm trying to work out how I could check to see if the number was already in the array before adding it but I can't get my head around the best way to do this.
Don't use an (Array)List, use a Set:
Set<Integer> set = ...;
while (set.size() < myArr.length) {
set.add(yourRandomNumber);
}
Use an ArrayList instead of an array. That way you would just need to use ArrayList#contains(obj) method to test whether the id is already in the ArrayList or not.
Or, you can just work with a HashSet, which will work faster with its HashSet#contains() method.
You can create a Set of the numbers. E.g.:
Set<Integer> intSet = new HashSet<Integer>();
while(intSet.size() < myArr.length) {
intSet.add(getNextRandomInt());
}
Then yo can do anything with that Set.
So, if you need an array, just call:
Integer[] intArray = intSet.toArray(new Integer[myArr.length]);
or, if you need an ArrayList or int[] array:
// ArrayList:
List<Integer> ints = new ArrayList<Integer>();
ints.addAll(intSet);
// int[] array:
int[] intArray = new int[myArr.length];
for( int i = 0; i<intArray.length; ++i) {
intArray[i] = int.get(i);
}
Anything which involves looping until you find enough unique random numbers is never guaranteed to complete. It's possible, if extremely unlikely, that the random number generator will never output enough unique numbers in a reasonable amount of time.
(I know this will never happen in practice, but it's a theoretical possibility.)
A safe alternative is to choose one random number, and then increment it in a loop until you have enough numbers.
int n = new Random().nextInt(89999 - myArr.length) + 10000;
for (int i = 0; i < myArr.length; i++) {
idArr.add(n++);
}

Generate k distinct numbers less than n

The task is this: generate k distinct positive numbers less than n without duplication.
My method is the following.
First create array size of k where we should write these numbers:
int a[] = new int[k];
//Now I am going to create another array where I check if (at given number
//position is 1 then generate number again, else put this number in an
//array and continue cycle.
I put a piece here of code and explanations.
int a[]=new int[k];
int t[]=new int[n+1];
Random r=new Random();
for (int i==0;i<t.length;i++){
t[i]=0;//initialize it to zero
}
int m=0;//initialize it also
for (int i=0;i<a.length;i++){
m=r.nextInt(n);//random element between 0 and n
if (t[m]==1){
//I have problems with this. I want in case of duplication element
//occurs repeat this steps afain until there will be different number.
else{
t[m]=1;
x[i]=m;
}
}
So I fill concret my problem: if t[m]==1. It means that this element occurs already so I want to
generate a new number, but problem is that number of generated numbers will
not be k because if i==0 and occurs duplicate element and we write continue then it will switch at i==1.
I need like goto for the repeat step. Or:
for (int i=0;i<x.length;i++){
loop:
m=r.nextInt(n);
if ( x[m]==1){
continue loop;
}
else{
x[m]=1;
a[i]=m;
continue; //Continue next step at i=1 and so on.
}
}
I need this code in Java.
It seems that you need a random sampling algorithm. You want to be able to choose m random items from the set {0,1,2,3...,n-1}.
See this post, where I wrote about 5 efficient algorithms for random sampling.
Following is Floyd's implementation, which can be useful in your case:
private static Random rnd = new Random();
...
public static Set<Integer> randomSample(int n, int m){
HashSet<Integer> res = new HashSet<Integer>(m);
for(int i = n - m; i < n; i++){
int item = rnd.nextInt(i + 1);
if (res.contains(item))
res.add(i);
else
res.add(item);
}
return res;
}
Create an array arr with n elements (1..n);
for i=1 to k {
result[i] = arr[rand]
delete arr[result[1]]
}

Categories

Resources