I tried to create a simple lottery program. Here is a problem: it still prints same numbers. For example I got 33 21 8 29 21 10 as output. Everytime when random number is generated, code checks if that number is already generated, then it creates a new random number but after that it doesn't check again. I couldn't find a way to do that.
public static void main(String[] args)
{
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++)
{
randomNum = (int) (Math.random() * 50); //Random number created here.
for (int x = 0; x < i; x++)
{
if (lottery[i] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);//If random number is same, another number generated.
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
There are 2 problems with your code:
you check if lottery[i] and randomNum are the same, it should be lottery[x]
when you re-generate a random number, you don't check it against the first numbers in lottery.
Here is a corrected version:
public static void main(String[] args) {
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
You are changing the random number while you are checking it. You need to pick one random number and check whether it is present or not.
BTW A shorter approach is to use a shuffle.
// give me all the number 1 to 50
List<Integer> list = IntStream.range(1, 51).boxed().collect(Collectors.toList());
// shuffle them.
Collections.shuffle(list);
// give me the first 6
System.out.println(list.subList(0, 6));
A simple solution, between the first (who could be very abstract for a not Java programmer) and the 2nd (not assuring the unicity of the number list).
Collection<Integer> liste = new ArrayList<Integer>();
for (int i = 0; i < 6; i++)
{
Boolean ap = false;
while (!ap)
{
Integer randomNumber = (int) (Math.random() * 50);
if (! liste.contains(randomNumber)){
liste.add(randomNumber);
ap = true;
}
}
}
for (Integer liste1 : liste) {
System.out.print(liste1+" ");
}
try this one, it creates 12 x (6 out of 45)
public static void main(String[] args) {
SecureRandom random = new SecureRandom();
for (int i = 0; i < 12; i++){
Integer[] tipp = new Integer[6];
int n = 0;
do {
int r = random.nextInt(45) + 1;
if (Arrays.asList(tipp).indexOf(r)<0){
tipp[n]= r;
n++;
}
} while (n<=5);
Arrays.sort(tipp);
System.out.println(Arrays.toString(tipp));
}
}
public static void main(String[] arg) {
int[] lottery = new int[6];
int randomNum;
c1:
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
if(randomNum == 0) {
continue c1;
}
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum ) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
This is the object class for making a ticket, it will create ONE ticket with ascending values at which whatever parameters you choose. This program won't run until you have a main method that you call. Make sure to import TreeSet.
import java.util.TreeSet;
public class TicketMaker{
private int numbersPerTicket;
private int lowestNumber;
private int highestNumber;
TicketMaker(){
numbersPerTicket=0;
lowestNumber=0;
highestNumber=0;
}
TicketMaker(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
this.numbersPerTicket=numbersPerTicket;
this.lowestNumber=lowestNumber;
this.highestNumber=highestNumber;
}
}
public boolean printTicket(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
if(numbersPerTicket > highestNumber){
System.out.println("Error not in-bounds");
return false;
}
int rand;
int count=0;
System.out.println("[Ticket Printed]");
TreeSet<Integer> set = new TreeSet<>();
do{
rand = (int)(Math.random()*highestNumber)+lowestNumber;
set.add(rand);
count++;
}while(set.size() != numbersPerTicket);
System.out.println(set);
return true;
}
else{
System.out.println("Error not in-bounds");
return false;
}
}
public boolean isValidTicketData(int numbers,int lowest,int highest){
if(lowest != 1){
if(highest == numbers)
return false;
}
if(numbers <= highest){
if(numbers > 0 && lowest >= 0 && highest >= lowest)
return true;
}
return false;
}
}
Related
I got this simple code and I want to simplify the comparsion with array in while loop
int[] numbers = new int[7];
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(number == numbers[0] || number == numbers[1] || number == numbers[2] || number == numbers[3] ||
number == numbers[4] || number == numbers[5] || number == numbers[6]) {
number = rand.nextInt();
}
numbers[i] = number;
}
for(int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
I want to find a way to simplify this part:
while(number == numbers[0] || number == numbers[1] || number == numbers[2] || number == numbers[3] ||
number == numbers[4] || number == numbers[5] || number == numbers[6])
How can I do that?
A simple solution to this would be to use Java 8 streams.
With streams it looks like this:
int[] numbers = new Random().ints(1, 46).distinct().limit(6).toArray();
Thanks Elliot, I failed to recognice that the number 0 would not be choosen as all ints are 0 at the beginning.
You could use a IntStream to test if any number from numbers doesn't match, and only increment when it does. Something like,
for (int i = 0; i < 7;) {
final int number = rand.nextInt(46);
if (IntStream.of(numbers).anyMatch(x -> x != number)) {
numbers[i] = number;
i++;
}
}
If your condition is complex just create a separate method which returns true or false, like that
public boolean isNumberInArray(int[] array, int number) {
for (int i = 0; i < array.length; i++) {
if (array[i] == number) {
return true;
}
}
return false;
}
while(isNumberInArray(numbers, number)) {
Now code looks much better
I would suggest you use a Map instead of an Array.
Please view the following code:
public class MyClass {
public static void main(String args[]) {
Map<Integer,Integer> numbers = new HashMap<>();
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(numbers.containsKey(number)) {
number = rand.nextInt(46);
}
// saving the index with the random value - to be used for sorting, etc...
numbers.put(number,i);
}
System.out.println(numbers);
}
}
And the output (Note that the map-key is the random value and the map-value is the index):
{17=2, 19=3, 22=0, 40=6, 42=4, 44=1, 30=5}
HashSet also works quite well (as pointed out by Johannes Kuhn):
public class MyClass {
public static void main(String args[]) {
Set<Integer> numbers = new HashSet<>();
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(numbers.contains(number)) {
number = rand.nextInt(46);
}
numbers.add(number);
}
System.out.println(numbers);
}
}
And the output:
[2, 35, 25, 10, 44, 30, 31]
If it is about just simplifying comparison using loop then you can do:
int[] numbers = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++) {
int number;
outer:
while (true) {
number = rand.nextInt(46);
for (int n : numbers) {
if (n == number)
continue outer;
}
break;
}
numbers[i] = number;
}
for (int number : numbers) {
System.out.println(number);
}
But you should use Set or Streams as mentioned in other Answers listed here..
my intend is to use simplest java (array and loops) to generate random numbers without duplicate...but the output turns out to be 10 repeating numbers, and I cannot figure out why.
Here is my code:
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
do {
for (int i=0; i<number.length; i++) {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
}
} while (!repeat);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
How about you use a Set instead? If you also want to keep track of the order of insertion you can use a LinkedHashSet.
Random r = new Random();
Set<Integer> uniqueNumbers = new HashSet<>();
while (uniqueNumbers.size()<10){
uniqueNumbers.add(r.nextInt(21));
}
for (Integer i : uniqueNumbers){
System.out.print(i+" ");
}
A Set in java is like an Array or an ArrayList except it handles duplicates for you. It will only add the Integer to the set if it doesn't already exist in the set. The class Set has similar methods to the Array that you can utilize. For example Set.size() is equivalent to the Array.length and Set.add(Integer) is semi-equivalent to Array[index] = value. Sets do not keep track of insertion order so they do not have an index. It is a very powerful tool in Java once you learn about it. ;)
Hope this helps!
You need to break out of the for loop if either of the conditions are met.
int[] number = new int[10];
int count=0;
int num;
Random r = new Random();
while(count<number.length){
num = r.nextInt(21);
boolean repeat=false;
do{
for(int i=0; i<number.length; i++){
if(num==number[i]){
repeat=true;
break;
}
else if(i==count){
number[count]=num;
count++;
repeat=true;
break;
}
}
}while(!repeat);
}
for(int j=0;j<number.length;j++){
System.out.print(number[j]+" ");
}
This will make YOUR code work but #gonzo proposed a better solution.
Your code will break the while loop under the condition: num == number[i].
This means that if the pseudo-generated number is equal to that positions value (the default int in java is 0), then the code will end execution.
On the second conditional, the expression num != number[i] is always true (otherwise the code would have entered the previous if), but, on the first run, when i == count (or i=0, and count=0) the repeat=true breaks the loop, and nothing else would happen, rendering the output something such as
0 0 0 0 0 0...
Try this:
int[] number = new int[10];
java.util.Random r = new java.util.Random();
for(int i=0; i<number.length; i++){
boolean repeat=false;
do{
repeat=false;
int num = r.nextInt(21);
for(int j=0; j<number.length; j++){
if(number[j]==num){
repeat=true;
}
}
if(!repeat) number[i]=num;
}while(repeat);
}
for (int k = 0; k < number.length; k++) {
System.out.print(number[k] + " ");
}
System.out.println();
Test it here.
I believe the problem is much easier to solve. You could use a List to check if the number has been generated or not (uniqueness). Here is a working block of code.
int count=0;
int num;
Random r = new Random();
List<Integer> numbers = new ArrayList<Integer>();
while (count<10) {
num = r.nextInt(21);
if(!numbers.contains(num) ) {
numbers.add(num);
count++;
}
}
for(int j=0;j<10;j++){
System.out.print(numbers.get(j)+" ");
}
}
Let's start with the most simple approach, putting 10 random - potentially duplicated - numbers into an array:
public class NonUniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
number[count++] = ThreadLocalRandom.current().nextInt(21);
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
So that gets you most of the way there, the only thing you know have to do is pick a number and check your array:
public class UniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
int candidate = ThreadLocalRandom.current().nextInt(21);
// Is candidate in our array already?
boolean exists = false;
for (int i = 0; i < count; i++) {
if (number[i] == candidate) {
exists = true;
break;
}
}
// We didn't find it, so we're good to add it to the array
if (!exists) {
number[count++] = candidate;
}
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
The problem is with your inner 'for' loop. Once the program finds a unique integer, it adds the integer to the array and then increments the count. On the next loop iteration, the new integer will be added again because (num != number[i] && i == count), eventually filling up the array with the same integer. The for loop needs to exit after adding the unique integer the first time.
But if we look at the construction more deeply, we see that the inner for loop is entirely unnecessary.
See the code below.
import java.util.*;
public class RandomDemo {
public static void main( String args[] ){
// create random object
Random r = new Random();
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
int i=0;
do {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
i++;
} while (!repeat && i < number.length);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
}
}
This would be my approach.
import java.util.Random;
public class uniquerandom {
public static void main(String[] args) {
Random rnd = new Random();
int qask[]=new int[10];
int it,i,t=0,in,flag;
for(it=0;;it++)
{
i=rnd.nextInt(11);
flag=0;
for(in=0;in<qask.length;in++)
{
if(i==qask[in])
{
flag=1;
break;
}
}
if(flag!=1)
{
qask[t++]=i;
}
if(t==10)
break;
}
for(it=0;it<qask.length;it++)
System.out.println(qask[it]);
}}
public String pickStringElement(ArrayList list, int... howMany) {
int counter = howMany.length > 0 ? howMany[0] : 1;
String returnString = "";
ArrayList previousVal = new ArrayList()
for (int i = 1; i <= counter; i++) {
Random rand = new Random()
for(int j=1; j <=list.size(); j++){
int newRand = rand.nextInt(list.size())
if (!previousVal.contains(newRand)){
previousVal.add(newRand)
returnString = returnString + (i>1 ? ", " + list.get(newRand) :list.get(newRand))
break
}
}
}
return returnString;
}
Create simple method and call it where you require-
private List<Integer> q_list = new ArrayList<>(); //declare list integer type
private void checkList(int size)
{
position = getRandom(list.size()); //generating random value less than size
if(q_list.contains(position)) { // check if list contains position
checkList(size); /// if it contains call checkList method again
}
else
{
q_list.add(position); // else add the position in the list
playAnimation(tv_questions, 0, list.get(position).getQuestion()); // task you want to perform after getting value
}
}
for getting random value this method is being called-
public static int getRandom(int max){
return (int) (Math.random()*max);
}
I would like to generate 10 random numbers. But before I add a number to the ArrayList, I need to check if my Arraylist already contains a number which is in the range between randomNumber - 50 and randomNumber + 50.
For example, if random number is 120 :
120-50=70
120+50=170
If the ArrayList contains a number between 70 and 170, I will not add it to my ArrayList and run again the cycle...
What is wrong with my code?
package ee.tlu;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Testing {
public Testing() {
List < Integer > numbers = new ArrayList < > ();
Random rand = new Random();
int number = rand.nextInt(5000);
int n = 0;
boolean listis = false;
numbers.add(number);
while (n < 10) {
number = rand.nextInt(5000);
for (int k = number - 50; k < number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
System.out.println(numbers);
}
public static void main(String[] args) {
new Testing();
}
}
You declare listis before you start the while-loop. It's never reset once it has been set to true. Move it inside the loop.
Also, you never check the number + 50 as you are having < instead of <= in your for-loop.
while (n < 10) {
boolean listis = false;
number = rand.nextInt(5000);
for (int k = number - 50; k <= number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
I'm not sure if it's the only problem, but you should reset your listis flag in each iteration of the while loop :
while (n < 10) {
listis = false; // added
number = rand.nextInt(5000);
for (int k = number - 50; k < number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
Otherwise, the first time you find a number that shouldn't be added, you will stop adding any numbers.
I would do this recursively. I haven't tested the below code, just a quick mockup on notepad. But hopefully this will help.
public class Testing {
public List < Integer > numbers = new ArrayList < > ();
public Testing() {
Random rand = new Random();
int number = rand.nextInt(5000);
// initial number in arraylist
numbers.add(number);
// add 9 more numbers to arraylist
addNumbers(9);
System.out.println(numbers);
}
public void addNumber(int amountLeft){
int newNumber = rand.nextInt(5000);
if(isValidNumberToAdd(newNumber))
{
numbers.add(newNumber);
}
if(amountLeft == 0)
{
return;
}
addNumber(amountLeft--);
}
public boolean isValidNumberToAdd(int newNumber)
{
Iterator<int> numbersIterator = numbers.iterator();
while (numbersIterator.hasNext()) {
int number = numbersIterator.next();
if(newNumber > number - 50 && newNumber < number + 50)
{
return false;
}
}
return true;
}
public static void main(String[] args) {
new Testing();
}
}
Simply use Set instead of List. Sets guarantee that:
Adding new element to the set works only if new element is not already present in the set.
I'm trying to get five random numbers printed that never repeat, based on a certain range provided by the user. Posted below is the code I have so far. I asked a similar question last night and got some great answers, but now I'm trying to accomplish this using only arrays and loops. Thanks.
package h1p2;
public class test{
public void method (int min, int max){
//Declare and initialize arrays and index variables
int rangeOne[];
int rangeMinMax[];
rangeOne = new int[5];
rangeMinMax = new int[max - min];
int z = min;
int i = 0;
int q = 0;
int rangeLength = rangeMinMax.length;
//need minimum/max differential of 50 or > to execute method
if (max - min < 50){
System.out.println("Please enter numbers with a differential of 50 or greater.");
}
//run if differential checks out
else{
//populate MinMax array with range specified by user
while (i < rangeLength){
rangeMinMax[i] = z;
z++;
i++;
}
}
//pick random number from MinMax array
int randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
int r = 0;
//populate rangeOne array with lotto numbers, forbidding duplicates
while (r < 5){
randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
rangeOne[r] = randomNumber;
randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
if (r == 1 && randomNumber == rangeOne[0]){
r--;
}
if (r == 2 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1])){
r--;
}
if (r == 3 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1] ||
randomNumber == rangeOne[2])){
r--;
}
if (r == 4 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1] ||
randomNumber == rangeOne[2] || randomNumber == rangeOne[3])){
r--;
}
else{
r++;}
}
//create string with results
String results = Integer.toString(rangeOne[0]) + " " + Integer.toString(rangeOne[1])
+ " " + Integer.toString(rangeOne[2]) + " " + Integer.toString(rangeOne[3]) +
" " + Integer.toString(rangeOne[4]);
//print results
System.out.println("MegaNumbers: " + results);
}
}
If all you need is a small amount of numbers, just use a linear search to simulate a set. Then keep generating random numbers until you've generated enough unique ones to suffice. Obviously this isn't the most efficient, but it is simple.
private static Random rand = new Random();
public static boolean contains(int [] data, int value)
{
for (int i = 0; i < data.length; i++)
{
if (data[i] == value)
{
return true;
}
}
return false;
}
public static int[] getRandom(int size, int lowerBound, int upperBound)
{
if (upperBound - lowerBound <= size)
{
throw new IllegalArgumentException("Range is too small!");
}
int totalRandoms = 0;
int[] randoms = new int[size];
while (totalRandoms != size)
{
int randNumber = rand.nextInt(upperBound - lowerBound) + lowerBound;
if (! contains(randoms, randNumber))
{
randoms[totalRandoms] = randNumber;
}
}
return randoms;
}
P.S. I've left some of the details up to you, I've just included a couple non-OO functions to give you a feel for a possible algorithm.
I wrote randomList() to accept three parameters:
1) the minimum random value
2) the maximum random value
3) and the number of random values the array should have.
The method first creates an array called choices filled with all the values from the min value to max value. It then starts a loop that fills a new array with values from choices. Whenever the loop chooses a random value from choices, it moves that value to the back of the choices array and updates lastIndex so it doesn't choose any values from the back of choices anymore.
An easier way to do this would be to make choices an ArrayList and simply delete the already taken values from it. But because we can't use ArrayLists, this code should work fine.
public static int[] randomList(int min, int max, int number) {
// fills an array with all numbers from min to max
int[] choices = new int[max - min + 1];
int lastIndex = choices.length - 1;
for(int i = min; i <= max; i++) {
choices[i - min] = i;
}
// fills the new array with values from choices
Random r = new Random();
int[] randomList = new int[number];
for(int i = 0; i < number; i++) {
int index = r.nextInt(lastIndex + 1);
randomList[i] = choices[index];
int copy = choices[lastIndex];
choices[lastIndex] = randomList[i];
choices[index] = copy;
lastIndex--;
}
return randomList;
}
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.