I'm having trouble with this assignment that requires me to create 50 random unique numbers without using ArrayLists. I'm required to use a boolean array that checks whether the random number has already been generated. Each number that is generated out of 50 will be set to true in the boolean array. Ex. Generating a number 23 would make check[23]=true. The problem I am having is an error in the while loop that keeps on generating a new random number even if there is no other unique number left. How can I solve this problem while still using a boolean array to check uniqueness.
int rnd;
Random rand=new Random();Random rand=new Random();
int[] nums = new int[50];
boolean[] check = new boolean[51];
rnd = rand.nextInt(50) +1;
for (int k = 0; k<50; k++)
{
//Loop for when there number is already chosen
while (check[rnd]==true)
{
rnd = rand.nextInt(50) +1;
}
//Sets the random unique number to a slot in the array
if(check[rnd]==false)
{
nums[k]=rnd;
check[rnd]=true;
}
rnd = rand.nextInt(50) +1;
}
System.out.println(nums);
Try this:
import java.util.Random;
public class random {
public static void main(String[] args) {
// TODO Auto-generated method stub
Random myRandom = new Random();
int[] numbers = new int[50];
boolean[] check = new boolean[50];
int amountFilled = 0;
int trial;
while (amountFilled < 50) {
trial = myRandom.nextInt(50);
if (!check[trial]) {
check[trial] = true;
numbers[amountFilled] = trial;
amountFilled++;
}
}
for (int i = 0; i < 50; i++) {
System.out.println(numbers[i]);
}
}
}
Your real problem was the System.out.println(nums); statement. It doesn't do what you what it to do. And the double Random rand=new Random();. The rest of the code is OK. I rewrote it in a clearer/simpler way, but what you had already works if you fix the output statement.
Few tweaks done:
public class Test {
public static void main(String args[]){
int rnd;
Random rand=new Random();
int[] nums = new int[50];
boolean[] check = new boolean[50];
for (int k = 0; k<50; k++)
{
rnd = rand.nextInt(50);
//Loop for when there number is already chosen
while (check[rnd])
{
rnd = rand.nextInt(50);
}
//Sets the random unique number to a slot in the array
nums[k]=rnd;
check[rnd]=true;
}
for(int num : nums){
System.out.println("\n" + num);
}
}
}
Related
I would like to generate 5 random numbers and if the number already exists, remove it and replace it with a new one. Repeating the process until all the numbers generated are unique. However, I am stuck as I keep getting duplicate values inside my array.
import java.util.Random;
import java.util.ArrayList;
public class Question2_NEW
{
public static void main (String[] args)
{
System.out.println("Generating 5 random numbers from 0 to 5...");
Random rand = new Random();
int generate = rand.nextInt((5) + 1);
ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
for (int i = 0; i < 5; i++)
{
generate = rand.nextInt((5) + 1);
randomNumbers.add(generate);
while (randomNumbers.contains(generate))
{
randomNumbers.remove(randomNumbers.get(i));
generate = rand.nextInt((5) + 1);
randomNumbers.add(generate);
break;
}
}
for (Integer i : randomNumbers)
{
System.out.println(i);
}
}
}
This happens because, inside the while loop, you are not checking that the replacement number isn't also already in the ArrayList. It is simply accepted without question.
A better solution is to check whether the number is valid before you add it:
for (int i = 0; i < 5; i++)
{
generate = rand.nextInt((5) + 1);
while (randomNumbers.contains(generate))
{
generate = rand.nextInt((5) + 1);
}
randomNumbers.add(generate);
}
Note that there are more efficient algorithms for this task. For one, membership checking is faster with a HashSet. For another, if you just want to generate a random permutation of the numbers 1 through N, a Fisher-Yates shuffle is the undisputed best solution. For something as tiny as 5 numbers, it probably doesn't matter though.
Write and call this method in your code.
private boolean arrayListIncludes(Integer i, ArrayList<Integer> randomNumbers) {
for(int x = 0; x<randomNumbers.size(); x++) {
if(randomNumbers.get(i).intValue() == i.intValue()) {
return true;
}
}
return false;
}
If you want to use List I would the following:
public static void main(String[] args) {
System.out.println("Generating 5 random numbers from 0 to 5...");
Random rand = new Random();
int generate;
List<Integer> randomNumbers = new ArrayList<Integer>();
for (int i = 0; i <= 5; i++) {
do {
generate = rand.nextInt((5) + 1);
} while (randomNumbers.contains(generate));
randomNumbers.add(generate);
}
for (Integer i : randomNumbers) {
System.out.println(i);
}
}
If you can also use sets:
public static void main(String[] args) {
System.out.println("Generating 5 random numbers from 0 to 5...");
Random rand = new Random();
Set<Integer> randomNumbers = new HashSet<Integer>();
while (randomNumbers.size() <= 5) {
randomNumbers.add(rand.nextInt((5) + 1));
}
for (Integer i : randomNumbers) {
System.out.println(i);
}
}
Edit: fixed issue with length of Set/ArrayList
This question already has answers here:
Creating random numbers with no duplicates
(20 answers)
Closed 8 years ago.
I'm in the process of creating a program that generates 50 random numbers between 1-999, but I can't figure out how to stop duplicates from showing up in the program. Any help would be appreciated.
public class Random50 //Name of my class
{
public static void main(String[] args)
{
int[] randomArray; //Declares a new array of integers
randomArray = new int[51];
Random rand = new Random();
for (int i = 1; i < randomArray.length; i++)
{
int n = rand.nextInt(1000);
randomArray[i] = n;
}
for (int i = 1; i < randomArray.length; i++) 4
{
System.out.printf("Number " + i + ": " + "%03d\n", randomArray[i]);
}
}
}
Simply do the following.
if (!randomArray[i].contains(n)) {
int n = rand.nextInt(1000);
randomArray[i] = n;
} else {
continue;
}
This block proofs the following:
- Has the array the n element in it? if no: add it - if yes: skip this pass of the array.
BTW: It would be better to increment the index of the array here AFTER the first condition is true and not for every pass. So rather something like this:
public class Random50 //Name of my class
{
public static void main(String[] args)
{
ArrayList<Integer> randomArray; //Declares a new array of integers
randomArray = new ArrayList<Integer>();
Random rand = new Random();
int i = 1;
for (; i < 51;)
{
if (!randomArray[i].contains(n)) {
int n = rand.nextInt(1000);
randomArray[i] = n;
i++;
} else {
continue;
}
}
for (int i = 1; i < randomArray.length; i++) 4
{
System.out.printf("Number " + i + ": " + "%03d\n", randomArray[i]);
}
}
}
I want to pick 8 random integers in the range 0-7.
int one = (int) (Math.random()*0)+7;
int two = (int) (Math.random()*0)+7;
// ...
int eight = (int) (Math.random()*0)+7;
However, no duplicate numbers are allowed. How can I improve this code to establish this?
Follow the below snippet and change the maxLimit and noOfItems according to your preference to get desired result.
Here the Set contains unique integers under specified limit.
public class RandomIntegers
{
public static final Random random = new Random();
public static final int maxLimit = 8;
public static final int noOfItems = 8;
public static void main( String[] args )
{
Set<Integer> uniqueRandomIntegerSet = new HashSet< Integer >();
while(uniqueRandomIntegerSet.size() < noOfItems)
uniqueRandomIntegerSet.add( random.nextInt( maxLimit ) );
}
}
I'm not sure if this violates your requirements, but you could just go like this:
public static void main(String[] args) {
List<Integer> randomZeroToSeven = new ArrayList<>();
for (int i = 0; i <= 7; i++) {
randomZeroToSeven.add(i);
}
Collections.shuffle(randomZeroToSeven);
}
Alternatively, you can skip the shuffle and just grab a random element out of the list every time you want a random number from 0-7. EG:
public static void main(String[] args) {
List<Integer> zeroToSeven = new ArrayList<>();
for (int i = 0; i <= 7; i++) {
zeroToSeven.add(i);
}
System.out.println(zeroToSeven.get(new Random().nextInt(8)));
}
Another way is to fill up an array / collection with all possibilities and pick from those. Each picked item is removed from the allowed array and put into the output array until you have picked all items.
This way you skip double picks and the execution is linear.
Something like this:
int desiredSize = 8;
List<Integer> allowed = new ArrayList<>();
for (int i = 0; i < desiredSize; i++) {
allowed.add(i);
}
List<Integer> output = new ArrayList<>();
Random random = new Random();
while (output.size() < desiredSize) {
int index = random.nextInt(allowed.size());
output.add(allowed.get(index));
allowed.remove(index);
}
If you need to generate numbers from min to max (including both), you can write
random.nextInt(max - min + 1) + min
public static void main(String[] args) throws IOException {
HashSet<Integer>list=new HashSet();
Random random=new Random();
while(list.size()<8){
list.add(random.nextInt(7 - 0 + 1) + 0); // OR list.add(random.nextInt(8));
}
System.out.println(list);
}
There are only 8 integers from 0-7 and so what you are really asking is for the numbers from 0-7 in a random order.
The quickest way to do this both coding and execution is to shuffle a set of integers.
public class Test {
public static void main(String[] args){
List<Integer> list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7);
Collections.shuffle(list);
for(int i : list){
System.out.println(i);
}
}
}
If you want to write a shuffle algorithm yourself you can do so by so swapping every item (bar the last) in an array with a random index. The reason you don't do the last is because it biases the outcome. See Fisher Yates Shuffle
Just because I couldn't resist here is a java implementation of Fisher Yates:
public class Test {
public static void main(String[] args){
Random rnd = new SecureRandom();
int[] arr = new int[]{0,1,2,3,4,5,6,7};
for(int i = 0; i < arr.length - 1; i++){
int swapIndex = rnd.nextInt(8);
int tmp = arr[i];
arr[i] = arr[swapIndex];
arr[swapIndex] = tmp;
}
System.out.println(Arrays.toString(arr));
}
}
This question already has answers here:
How to generate 6 different random numbers in java
(10 answers)
Closed 8 years ago.
I want to generate 6 different random numbers by using Math.random and store all of them into an array. How can I make sure that they are different? I only have this so far and this has a bug. I only need numbers between 1 and 49. ( 1 + (int) (Math.random() * 49) ).
public static void main (String []args) {
int []randomNumArray = new int [6];
randomNumArray[0] = randomNumber();
System.out.println(randomNumArray[0]);
for (int i = 1; i < 6; i++) {
for (int j = 0; j < i; j++) {
randomNumArray[i] = randomNumber();
do {
if (randomNumArray[i] == randomNumArray[j]) {
randomNumArray[i] = randomNumber();
}
} while(randomNumArray[i] == randomNumArray[j]);
}
System.out.println(randomNumArray[i]);
}
}
//This method is for generating random numbers
public static int randomNumber (){
return ( 1 + (int) (Math.random() * 49) );
}
Generate random numbers and keep adding them to a Set until its size =
6. A set can contain only unique elements. So, you are assured uniqueness.
EDIT :
public static void main(String[] args) {
Set<Integer> intSet = new LinkedHashSet<Integer>();
Random r = new Random();
while (intSet.size() <= 6) {
intSet.add(r.nextInt(49)); // or your method of generating random numbers
}
System.out.println(intSet);
}
Obviously, the set approach and shuffling the array are more efficient approaches, but given the context, here is a modification of the OP's code to achieve uniqueness, to address the "bug" in his code.
import java.util.*;
public class Main {
public static void main (String []args) {
int []randomNumArray = new int [6];
randomNumArray[0] = randomNumber();
System.out.println(randomNumArray[0]);
for (int i = 1; i < 6; i++)
{
int candidate;
boolean foundMatch;
do
{
candidate = randomNumber();
foundMatch = false;
for (int j = 0; j < i; j++)
if (candidate == randomNumArray[j])
foundMatch = true;
} while (foundMatch);
randomNumArray[i] = candidate;
System.out.println(randomNumArray[i]);
}
}
//This method is for generating random numbers
public static int randomNumber (){
return ( 1 + (int) (Math.random() * 49) );
}
}
I would like to generate random numbers in ascending order, for instance: 0, 2, 3, 5 .. 100, but not 2, 0, 5 ..
This is what I came up with so far:
public static int vol=5;
public static void main(String[] args) {
int randno = getRandNum();
vol = vol+randno;
System.out.println(getRandNum());
}
private static int getRandNum() {
Random r = new Random();
for (int i =0; i<10; i++)
{
int v=r.nextInt(vol);
System.out.println("r"+v);
}
return vol;
}
How could I achieve the goal stated above?
/**
* Generates random numbers, returning an array of ascending order.
* #param amount The amount of numbers to generate.
* #param max The maximum value to generate.
* #return An array of random integers of the specified length.
*/
public static int[] generateIncreasingRandoms(int amount, int max) {
int[] randomNumbers = new int[amount];
Random random = new Random();
for (int i = 0; i < randomNumbers.length; i++) {
randomNumbers[i] = random.nextInt(max);
}
Arrays.sort(randomNumbers);
return randomNumbers;
}
You could use it like so:
// Generates 10 random numbers of value 0 to 100,
// printing them in ascending order
for (int number : generateIncreasingRandoms(10, 100)) {
System.out.print(number + " ");
}
Or if you're a micro-optimization kind of person and do not wish to sort,
/**
* Generates random numbers, returning an array of ascending order.
* #param amount The amount of numbers to generate.
* #param max The maximum value to generate.
* #return An array of random integers of the specified length.
*/
public static int[] generateIncreasingRandomWithoutSorting(int amount, int max) {
int[] randomNumbers = new int[amount];
double delta = max / (float)amount;
Random random = new Random();
for (int i = 0; i < randomNumbers.length; i++) {
randomNumbers[i] = (int)Math.round(i*delta + random.nextDouble() * delta);
}
return randomNumbers;
}
Use case:
// Generates 10 random numbers of value 0 to 100,
// printing them in ascending order
for (int number : generateIncreasingRandomWithoutSorting(10, 100)) {
System.out.print(number + " ");
}
The reason that each number is between 0-10, 10-20, 20-30.. in this use case is that if I simply allow for the entire range and you get a 100 on the first try you're going to end up with an entire array of 100s.
Being more controlled, with this solution you are not really getting what you're asking for ("10 numbers of 0 to 100 sorted ascendingly") since it modifies the range for each consecutive number. (like any other solution that doesn't require sorting)
Ben Barkay's answer is good, but if you don't want to create a set of numbers in one step, but you want to get one number after another, you can do something like this:
private static final int MAX = 5;
private Random rand = new Random();
private int maxRand = 0;
public int getIncreasingRandomNumber() {
maxRand = rand.nextInt(MAX);
return maxRand;
}
what about this?
public class increasing {
public static void main (String[] args) {
Random r = new Random();
int totalNums = 100;
int count = 0;
int lastVal = 0;
int currVal = 0;
while(count < totalNums) {
currVal = r.nextInt(200);
lastVal = lastVal + currVal;
System.out.println(lastVal + ",");
count++;
}
}
}