Non-repeating random numbers inside array JAVA - java

I would like to generate 6 numbers inside an array and at the same time, having it compared so it will not be the same or no repeating numbers. For example, I want to generate 1-2-3-4-5-6 in any order, and most importantly without repeating. So what I thought is to compare current array in generated array one by one and if the number repeats, it will re-run the method and randomize a number again so it will avoid repeating of numbers.
Here is my code:
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int Array[] = new int [6];
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen();
for(int loop = 0; loop <6 ; loop++)
{
if(Array[index] == Array[loop])
{
Array[index] = numGen();
}
}
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen()
{
int random = (int)(1+Math.random()*6);
return random;
}
}
I've been thinking it for 2 hours and still cant generate 6 numbers without repeating.
Hope my question will be answered.
Btw, Im new in codes so please I just want to compare it using for loop or while loop and if else.

You can generate numbers from, say, 1 to 6 (see below for another solution) then do a Collections.shuffle to shuffle your numbers.
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
Collections.shuffle( l );
By doing this you'll end up with a randomized list of numbers from 1 to 6 without having twice the same number.
If we decompose the solution, first you have this, which really just create a list of six numbers:
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
So at this point you have the list 1-2-3-4-5-6 you mentioned in your question. You're guaranteed that these numbers are non-repeating.
Then you simply shuffle / randomize that list by swapping each element at least once with another element. This is what the Collections.shuffle method does.
The solutions that you suggested isn't going to be very efficient: depending on how big your list of numbers is and on your range, you may have a very high probability of having duplicate numbers. In that case constantly re-trying to generate a new list will be slow. Moreover any other solution suggesting to check if the list already contains a number to prevent duplicate or to use a set is going to be slow if you have a long list of consecutive number (say a list of 100 000 numbers from 1 to 100 000): you'd constantly be trying to randomly generate numbers which haven't been generated yet and you'd have more and more collisions as your list of numbers grows.
If you do not want to use Collections.shuffle (for example for learning purpose), you may still want to use the same idea: first create your list of numbers by making sure there aren't any duplicates and then do a for loop which randomly swap two elements of your list. You may want to look at the source code of the Collections.shuffle method which does shuffle in a correct manner.
EDIT It's not very clear what the properties of your "random numbers" have to be. If you don't want them incremental from 1 to 6, you could do something like this:
final Random r = new Random();
final List<Integer> l = new ArrayList<Integer>();
for (int j = 0; j < 6; j++ ) {
final int prev = j == 0 ? 0 : l.get(l.size() - 1);
l.add( prev + 1 + r.nextInt(42) );
}
Collections.shuffle( l );
Note that by changing r.nextInt(42) to r.nextInt(1) you'll effectively get non-repeating numbers from 1 to 6.

You have to check if the number already exist, you could easily do that by putting your numbers in a List, so you have access to the method contains. If you insist on using an array then you could make a loop which checks if the number is already in the array.
Using ArrayList:
ArrayList numbers = new ArrayList();
while(numbers.size() < 6) {
int random = numGen(); //this is your method to return a random int
if(!numbers.contains(random))
numbers.add(random);
}
Using array:
int[] numbers = new int[6];
for (int i = 0; i < numbers.length; i++) {
int random = 0;
/*
* This line executes an empty while until numGen returns a number
* that is not in the array numbers yet, and assigns it to random
*/
while (contains(numbers, random = numGen()))
;
numbers[i] = random;
}
And add this method somewhere as its used in the snippet above
private static boolean contains(int[] numbers, int num) {
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == num) {
return true;
}
}
return false;
}

Here is the solution according to your code -
You just need to change the numGen method -
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
Complete code is -
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
int Array[] = new int [6];
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen(Array);
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
}

Use List instead of array and List#contains to check if number is repeated.

you can use a boolean in a while loop to identify duplicates and regenerate
int[] array = new int[10]; // array of length 10
Random rand = new Random();
for (int i = 0 ; i < array.length ; i ++ ) {
array[i] = rand.nextInt(20)+1; // random 1-20
boolean found = true;
while (found) {
found = false;
// if we do not find true throughout the loop it will break (no duplicates)
int check = array[i]; // check for duplicate
for (int j = 0 ; j < i ; j ++) {
if ( array[j] == check ) {
found = true; // found duplicate
}
}
if (found) {
array[i] = rand.nextInt(20)+1 ; // replace
}
}
}
System.out.println(Arrays.toString(array));

You may use java.util.Random. And please specify if you want any random number or just the number 1,2,3,4,5,6. If you wish random numbers then , this is a basic code:
import java.util.*;
public class randomnumber
{
public static void main(String[] args)
{
Random abc = new Random();
int[] a = new int[6];
int limit = 100,c=0;
int chk = 0;
boolean y = true;
for(;c < 6;)
{
int x = abc.nextInt(limit+1);
for(int i = 0;i<a.length;i++)
{
if(x==a[i])
{
y=false;
break;
}
}
if(y)
{
if(c!=0)if(x == (a[c-1]+1))continue;
a[c]=x;
c++;
}
}
for (Integer number : a)
{
System.out.println(number);
}
}
}
if you don't understand the last for loop , please tell , i will update it.

Use List and .contains(Object obj) method.
So you can verify if list has the random number add before.
update - based on time you can lost stuck in random loop.
List<Integer> list = new ArrayList<Integer>();
int x = 1;
while(x < 7){
list.add(x);
x++;
}
Collections.shuffle(list);
for (Integer number : list) {
System.out.println(number);
}
http://docs.oracle.com/javase/7/docs/api/java/util/List.html#contains(java.lang.Object)

Related

randomly generate 100 unique numbers using Math.random [duplicate]

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);
}

How do you find the mode of an Array in java?

I'm new to java and I have a homework assignment where I need to find the Mean, median and Mode of an Array. For some reason my code is not putting out the correct answer.
Here is the code I was provided to create the Arrays:
public static void main(String[] args) {
int[] test01 = new int[]{2,2,2,2,2};
int[] test01Results = new int[]{2,2,2,2};
int[] test02 = new int[]{1,2,1,3,5,6,6,1,2,2,2,99,100};
int[] test02Results = new int[]{2,2,17,100};
int[] test03 = new int[]{100,200,300,400,300};
int[] test03Results = new int[]{300,300,260,400};
int[] test04 = new int[]{100};
int[] test04Results = new int[]{100,100,100,100};
int[] test05 = new int[]{100,1};
int[] test05Results = new int[]{1,100,50,100};
Here is what I came up with to try to calculate the Mode:
public int mode() {
int result = 0;
// Add your code here
int repeatAmount = 0; //the amount of repeats accumulating for the current i
int highestRepeat=0; // the highest number of repeats so far
for (int i=0; i<numberArray.length; i++) {
for (int j=i; j<numberArray.length; j++) {
if (i != j && numberArray[i] == numberArray[j]) {
repeatAmount++;
if (repeatAmount>highestRepeat) {
result=numberArray[i];
}
repeatAmount = highestRepeat;
}
repeatAmount=0; // resets repeat Count for next comparison
}
}
return result;
}
I'm getting the correct results for tests 1, 2 and 3 but getting the wrong result for Tests 4 and 5. Does anyone know what I'm doing wrong?
Thanks!
You never assign anything except 0 to highestRepeat. This should work:
public int mode() {
int result = 0;
int highestRepeat=0;
for (int i=0; i<numberArray.length; i++) {
int repeatAmount = 1;
for (int j = i + 1; j < numberArray.length; j++) {
if (numberArray[i] == numberArray[j]) {
repeatAmount++;
if (repeatAmount > highestRepeat) {
result = numberArray[i];
highestRepeat = repeatAmount;
}
}
}
}
return result;
}
Some other improvements:
By starting the inner loop at i+1 you can skip the check if i != j.
By declaring repeatAmount inside the outer loop you can skip
setting it to zero after the inner loop.
If you need some performance, consider using a HashMap for counting the equal array entries.

How to remove duplicates from array using for loop

In this code I have found duplicates from an array and I want to remove them. The output then will be unique generated numbers. I am required to use math.random and modulo. Anyone have any clues? I tried to store them in an array but then the original array has 0's and 0 is part of my domain for the random number generation (from 0 to 52).
public class Decks {
public static void main(String[] args) {
generate();
}
public static void generate() {
int deckOfCard[] = new int[52];
for (int counts = 0; counts < 52; counts++) {
deckOfCard[counts] = (int) (Math.random() * 51);
}
for (int i = 0; i < deckOfCard.length - 1; i++) {
for (int j = i + 1; j < deckOfCard.length; j++) {
if ((deckOfCard[i] == (deckOfCard[j])) && (i != j)) {
System.out.println("DUPLICATE " + deckOfCard[i]);
}
}
}
for (int count = 0; count < deckOfCard.length; count++) {
System.out.print("\t" + deckOfCard[count]);
}
}
Why dont you try using HashSet instead of arrays ? As you know sets only store unique values so you wont have any duplicates.
You must validate the numbers generated during the random number generation like this:
import java.util.Random;
public class Decks {
public static void main(String[] args) {
Random myRandom = new Random();
int[] num = new int[53];
boolean[] check = new boolean[53];
int all = 0;
int ranNum;
while (all < 53) {
ranNum = myRandom.nextInt(53);
if (!check[ranNum]) {
check[ranNum] = true;
num[all] = ranNum;
all++;
}
}
for (int i = 0; i < 53; i++) {
System.out.println(num[i]);
}
}
}
I suggest not including number 0 because it does not exist in a real deck of cards (ACE being the lowest having the number value of 1). I just included it right here because in my understanding, 0 is included in your desired output.
Considering time complexity, you can sort them first, which at best case takes nlogn time, and then use O(1) to find duplicated elements out.

Given an array with 2 integers that repeat themselves the same no. of times, how do i print the two integers

i'm new to this, Say if you typed 6 6 6 1 4 4 4 in the command line, my code gives the most frequent as only 6 and i need it to print out 6 and 4 and i feel that there should be another loop in my code
public class MostFrequent {
//this method creates an array that calculates the length of an integer typed and returns
//the maximum integer...
public static int freq(final int[] n) {
int maxKey = 0;
//initiates the count to zero
int maxCounts = 0;
//creates the array...
int[] counts = new int[n.length];
for (int i=0; i < n.length; i++) {
for (int j=0; j < n[i].length; j++)
counts[n[i][j]]++;
if (maxCounts < counts[n[i]]) {
maxCounts = counts[n[i]];
maxKey = n[i];
}
}
return maxKey;
}
//method mainly get the argument from the user
public static void main(String[] args) {
int len = args.length;
if (len == 0) {
//System.out.println("Usage: java MostFrequent n1 n2 n3 ...");
return;
}
int[] n = new int[len + 1];
for (int i=0; i<len; i++) {
n[i] = Integer.parseInt(args[i]);
}
System.out.println("Most frequent is "+freq(n));
}
}
Thanks...enter code here
Though this may not be a complete solution, it's a suggestion. If you want to return more than one value, your method should return an array, or better yet, an ArrayList (because you don't know how many frequent numbers there will be). In the method, you can add to the list every number that is the most frequest.
public static ArrayList<Integer> freq(final int[] n) {
ArrayList<Integer> list = new ArrayList<>();
...
if (something)
list.add(thatMostFrequentNumber)
return list;
}
The solutions looks like this:
// To use count sort the length of the array need to be at least as
// large as the maximum number in the list.
int[] counts = new int[MAX_NUM];
for (int i=0; i < n.length; i++)
counts[n[i]]++;
// If your need more than one value return a collection
ArrayList<Integer> mf = new ArrayList<Integer>();
int max = 0;
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] > max)
max = counts[i];
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] == max)
mf.add(i);
return mf;
Well you can just do this easily by using the HashTable class.
Part 1. Figure out the frequency of each number.
You can do this by either a HashTable or just a simple array if your numbers are whole numbrs and have a decent enough upper limit.
Part 2. Find duplicate frequencies.
You can just do a simple for loop to figure out which numbers are repeated more than once and then print them accordingly. This wont necessarily give them to you in order though so you can store the information in the first pass and then print it out accordingly. You can use a HashTable<Integer,ArrayList<Integer> for this. Use the key to store frequency and the ArrayList to store the numbers that fall within that frequency.
You can maintain a "max" here while inserting into our HashTable if you only want to print out only the things with most frequency.
Here is a different way to handle this. First you sort the list, then loop through and keep track of the largest numbers:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int n[] = { 6, 4, 6, 4, 6, 4, 1 };
List<Integer> maxNums = new ArrayList<Integer>();
int max = Integer.MIN_VALUE;
Integer lastValue = null;
int currentCount = 0;
Arrays.sort(n);
for( int i : n ){
if( lastValue == null || i != lastValue ){
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount > max ){
maxNums.clear();
maxNums.add(lastValue);
max = currentCount;
}
lastValue = i;
currentCount = 1;
}
else {
currentCount++;
}
System.out.println("i=" + i + ", currentCount=" + currentCount);
}
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount >= max ){
maxNums.clear();
maxNums.add(lastValue);
}
System.out.println(maxNums);
}
}
You can try it at: http://ideone.com/UbmoZ5

Creating unique random numbers in Java

I was making a Random number (sort of a guessing game) and have come up with the ff. code to generate 10 one or two-digit numbers(1 or 10 up to 40):
public void generate()
{
for(int i=0; i<=1; i++)
{
for(int l=0; l<10; l++)
{
Random rdm=new Random();
arr[l] = rdm.nextInt(range)+1;
}
}
}
However, this code only answers the need to generate 10 random one or two-digit numbers. I need to make this program generate unique random numbers. How can I do that?
sorry for the late update... what I want to do with this program is that if the array contains a duplicate, that duplicate would be replaced with a unique one...
==============SOLVED================
NEW PROBLEM:
HashSet set=new HashSet();
Random random=new Random();
while(set.Size()<10)
{
set.add(random.nextInt(range)+1);
}
lbtest.setText(set.toString());
bgen.setEnabled(false);
gametext.setText("");
As requested by ggrigery:
here's the updated code in reference to ggrigery's suggestion.
Another option is to use shuffle.
List<Integer> all = new ArrayList<>();
for(int i=1;i<=range;i++) all.add(i);
Collections.shuffle(all);
List<Integer> selected = all.subList(0, 10);
If you are selecting every element, it can take a long time to find the last random value if you are discarding duplicates. This approach takes the same amount of time whether you select one or all elements.
HashSet<Integer> set = new HashSet<Integer>();
Random random = new Random();
int i = 0;
while(set.size() < 10){
set.add(random.nextInt(40) + 1);
i++;
}
System.out.println(set);
System.out.println(i);
Set guarantees unique elements. Then you may take result and convert it in whatever collection or array you want.
public List<Integer> generate() {
Random random = new Random();
Set<Integer> set = new LinkedHashSet<Integer>();
for(int i = 0; i < numberCount; i++) {
set.add(random.nextInt(range));
}
return new ArrayList<Integer>(set);
}
Do a search inside the array to know if the value is there:
private boolean isInsideArray(int randomNumber, int[] arr){
for(int x = 0; x < arr.length; x++){
if(arr[x] == randomNumber) return true;
}
return false;
}
Just call this function when you want to know if a number is inside the array.
NOTE: this code is untested, it is just an example to help you out. Also not the most elegant solution, there are many methods in Java that can help you accomplish this without cycling the entire array.
public void generate() {
Random rdm = new Random();
int i = 0;
while (i < 10) {
int j = rdm.nextInt(range) + 1;
if (!arrayContains(j)) {
arr[i] = j;
i++;
}
}
}
public boolean arrayContains(int i) {
for (int k = 0; k < arr.length; k++) {
if (arr[k] == i)
return true;
}
return false;
}
This should do the job. Could be more elegant though.

Categories