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]);
}
}
}
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
When user enter number 1 smaller than number 2 swap does not work,
but when number 1 is larger than number 2 it works. I don't understand why this is occurring. I would appreciate some suggestions or help.
package javaapplication36;
public class JavaApplication36 {
static Scanner s = new Scanner(System.in);
// main method
public static void main(String[] args) {
int[] arr = new int[10];
input(arr);
System.out.println("Enter n1 :");
int n1 = s.nextInt();
System.out.println("Enter n2 : ");
int n2 = s.nextInt();
display(arr);
int temp = 0;
int index_a = index(arr, n1);
int index_b = index(arr, n2);
if (index(arr, n1) != -1 && index(arr, n2) != -1) {
temp = arr[index_a];
arr[index_a] = arr[index_b];
arr[index_b] = temp;
}
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
public static void display(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
public static void input(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println("Enter number : " + (i + 1));
arr[i] = s.nextInt();
}
}
public static int index(int[] arr, int n) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == n)
return i;
}
return -1;
}
}
I tried this and could not find anything wrong. To make debugging this easier I recommend you populate your array using random numbers.
Create an instance of Random
Random rand = new Random();
And assign the output to your array variable.
arr = rand.ints(10,1,15).toArray();
The arguments to rand.ints are.
10 - the number of elements
1 - the start of the range of numbers
15 - the end of the range (not including that number)
So that call would generate 10 numbers from 1 to 14 inclusive.
One possibility for any problems could be duplicate numbers in your array and finding the correct one to swap. But I was unable to reproduce the error.
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 just want to know how to limit to number of times a random number appears. I have generated random numbers of 1 to 10 and want to limit each number to appear 4 times.
myArray[i][j] = rand.nextInt(11);
for (int i=0; i < myArray.length; i++) {
for (int j=0; j < myArray[i].length; j++) {
myArray[i][j] = rand.nextInt(11);
System.out.print(" " + myArray[i][j]);
The code above creates the randoms numbers. Just want to limit them.
Since you are limited to 10 * 4 = 40 numbers you can use a list and randomize the index :
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i < 11; ++i) {
for (int j = 0; j < 4; ++j)
numbers.add(i);
}
And then when you assign a random number :
int i = rand.nextInt(numbers.size());
myArray[i][j] = numbers.get(i);
numbers.remove(i);
This assumes your two dimensional will not contain more then 40 numbers
My solution stores the result in arrayList:
public class Example {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
final int range = 10;
int[] numbers = new int[range + 1];
int sum = 0;
final int noOfOccurances = 4;
final int size = range * noOfOccurances;
Arrays.fill(numbers, 0);
Random generator = new Random();
List<Integer> numbersArray = new ArrayList<>();
while (sum != size) {
int randomNumber = generator.nextInt(range) + 1;
if (numbers[randomNumber] != noOfOccurances) {
numbers[randomNumber]++;
sum++;
numbersArray.add(randomNumber);
}
}
System.out.println(numbersArray);
}
}
How about storing the count of the generated int's in an array, or Map, or anything?
Map<Integer, Integer> randomCounts = new HashMap<Integer, Integer>();
... your for loops
myArray[i][j] = rand.nextInt(11);
if (randomCounts.containsKey(myArray[i][j])) {
randomCounts.put(myArray[i][j],randomCounts.get(myArray[i][j])+1);
} else {
randomCounts.put(myArray[i][j],1);
}
And if you want to check them, just iterate through your map, and voilá. :)
You can make a method to check if the generated number exists more than 4 times in the array and create a new random number if it does. It should look like this:
import java.util.Random;
public class rndNumberGenerator {
public static void main (String[] args) {
int[][] myArray = new int[2][5];
Random rand = new Random();
int randomNumber;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 5; j++) {
do {
randomNumber = rand.nextInt(11);
} while(overMax(myArray, randomNumber) == true);
myArray[i][j] = randomNumber;
System.out.print(" " + myArray[i][j]);
}
}
}
public static boolean overMax(int[][] array, int number) {
int max = 4;
int count = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 5; j++) {
if (array[i][j] == number) {
count++;
}
}
}
if (count >= max)
return true;
else
return false;
}
}
Hope this helped you, if you have any other questions feel free to ask.
I take suggestion by pshemek (vote up): instead the ArrayList, I use the Set because it can't contain duplicate numbers and you have'nt to espicitate control.
An implementation: the copy{right, left} is of pshemek, I had only extended the idea:)
public class Example {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int[] numbers = new int[11];
int sum = 0;
final int range = 10;
final int noOfOccurances = 4;
Arrays.fill(numbers, 0);
Random generator = new Random();
Set<Integer> numbersArray = new TreeSet<Integer>();
while (sum != range * noOfOccurances) {
int randomNumber = generator.nextInt(range) + 1;
sum++;//correction for first comment
numbersArray.add(randomNumber); // randomNumber will never be twice: a Set cointains ever one and only one instance of an determinated element
}
System.out.println(numbersArray);
}
}//end class
You could write your own:
public static class CountedRandom {
// My rng.
Random rand = new Random();
// Keeps track of the counts so far.
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
// The limit I must apply.
final int limit;
public CountedRandom(int limit) {
this.limit = limit;
}
public int nextInt(int l) {
int r;
do {
// Keep getting a new number until we hit one that has'n been overused.
r = rand.nextInt(l);
} while (count(r) >= limit);
return r;
}
private int count(int r) {
// How many times have we seen this one so far.
Integer counted = counts.get(r);
if ( counted == null ) {
// Never!
counted = new Integer(0);
}
// Remember the new value.
counts.put(r, counted + 1);
// Returns 0 first time around.
return counted;
}
}
public void test() {
CountedRandom cr = new CountedRandom(4);
for ( int i = 0; i < 50; i++ ) {
System.out.print(cr.nextInt(4)+",");
}
System.out.println();
}
Note that this will hang if you ask for too may numbers in too small a range (as I have in my test).
Prints
2,0,1,2,1,1,3,3,0,3,0,2,2,0,1,3,
and then hangs.
This code takes a random sampling of numbers, plugs them into an array, counts the odd numbers, and then lets the user pick an integer to see if it matches. This works great now with just arrays, but I want to convert it to work with ArrayLists. What's the easiest way to do this?
import java.util.Scanner;
import java.util.Random;
public class ArrayList {
public static void main(String[] args) {
// this code creates a random array of 10 ints.
int[] array = generateRandomArray(10);
// print out the contents of array separated by the delimeter
// specified
printArray(array, ", ");
// count the odd numbers
int oddCount = countOdds(array);
System.out.println("the array has " + oddCount + " odd values");
// prompt the user for an integer value.
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer to find in the array:");
int target = input.nextInt();
// Find the index of target in the generated array.
int index = findValue(array, target);
if (index == -1) {
// target was not found
System.out.println("value " + target + " not found");
} else {
// target was found
System.out.println("value " + target + " found at index " + index);
}
}
public static int[] generateRandomArray(int size) {
// this is the array we are going to fill up with random stuff
int[] rval = new int[size];
Random rand = new Random();
for (int i = 0; i < rval.length; i++) {
rval[i] = rand.nextInt(100);
}
return rval;
}
public static void printArray(int[] array, String delim) {
// your code goes here
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
if (i < array.length - 1)
System.out.print(delim);
else
System.out.print(" ");
}
}
public static int countOdds(int[] array) {
int count = 0;
// your code goes here
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 == 1)
count++;
}
return count;
}
public static int findValue(int[] array, int value) {
// your code goes here
for (int i = 0; i < array.length; i++)
if (array[i] == value)
return i;
return -1;
}
}
I rewrite two of your functions,maybe they will useful for you.
public static List<Integer> generateRandomList(int size) {
// this is the list we are going to fill up with random stuff
List<Integer> rval = new ArrayList<Integer>(size);
Random rand = new Random();
for (int i = 0; i < size; i++) {
rval.add(Integer.valueOf(rand.nextInt(100)));
}
return rval;
}
public static int countOdds(List<Integer> rval) {
int count = 0;
for (Integer temp : rval) {
if (temp.intValue() % 2 == 1) {
count++;
}
}
return count;
}