Preventing Duplicate Integers in Array - java

I'm making an program for class that calls for the program to create 6 randomly generated integers in the range 1-40 and put them into an array. The integers have to be unique so there can't be a situation where a number certain number repeats. The array is then passed onto another method that sorts the array in ascending order. My problem is that I can't get my code to generate 6 unique numbers. My code is as follows:
private static void getComputer(int computerNumbers, int[] cN)
{
Random randomNumbers = new Random();
for (int i = 0; i < computerNumbers;)
{
int computerStored = randomNumbers.nextInt(39)+1;
if (computerStored == cN[0] || computerStored == cN[1] || computerStored == cN[2] ||
computerStored == cN[3] || computerStored == cN[4] || computerStored == cN[5])
continue;
else
computerStored = cN[i];
i++;
}
}
The above block of code outputs an array of 0,0,0,0,0,0. I just can't find out why. Any help would be much appreciated. Thank you.
Just for clarification, I know how to do a basic randomgenerator.
private static void getComputer(int computerNumbers, int[] cN)
{
Random randomNumbers = new Random();
for (int i = 0; i < computerNumbers; i++)
cN[i] = randomNumbers.nextInt(39)+1;
}

You probably meant
cN[i] = computerStored;
Note also that there are three issues with this code: You're passing in the size of the array, which is bad form in Java, you can never get zero (which is technically not a bug in this case since you're dealing with just 1-40), and your conditional is really unwieldy. Instead, I'd do this:
for(int i = 0; i < cN.length;) {
int candidate = randomNumbers.nextInt(39) + 1;
// actually, I'd either move this into another method or use a `Set` in the first place
boolean duplicate = false;
for(int j = 0; j < i || !duplicate; j++)
if(candidate == cN[j])
duplicate = true;
if(!duplicate)
cN[i++] = candidate;
}

I would approach this in a different way:
create a list of integers 1-40
shuffle them
create an array from the first 6 elements
Like this:
List<Integer> list = new ArrayList<>(40);
for (int i = 1; i < 41; i++)
list.add(i);
Collections.shuffle(list);
int[] cN = new int[6];
for (int i = 0; i < cN.length; i++)
cN[i] = list.get(i);
The advantage of this approach is you don't have to deal with the issue of duplicates, and it makes use of the JDK to do the randomizing.

Related

Numerical sort with multiple lists of ascending values

I've had trouble articulating a simple way to break this question down in to a question title, and therefore a google search.
I'm wondering if there is a sorting algorithm already defined that can sort an array of numbers without keeping pairs adjacent. Easier to explain with an example:
Values:
1,3,5,2,1,3,2,4
A normal numerical sort would come out as:
1,1,2,2,3,3,4,5
What I would like:
1,2,3,4,5,1,2,3
I could hack this together, I just want to know if there is a name for this kind of sort.
Nothing exists, but the algorithm is simple enough:
separate dupes into tmplist
sort list
add list to result
switch list and tmplist
repeat while list is non-empty
You may use the common selection sort algorithm and make some modification to it.
For example:
static void modifiedSelectionSort(int[] arr)
{
Integer lastSelection = null;
for (int i = 0; i < arr.length - 1; i++)
{
// Find the minimum element in unsorted array which is greater than lastSelection
Integer minIdx = null;
for (int j = i; j < arr.length; j++)
if ((minIdx == null || arr[j] < arr[minIdx]) && (lastSelection == null || arr[j] > lastSelection))
minIdx = j;
// Check whether the last selection is the greatest number
if (minIdx == null) {
lastSelection = null;
i--;
} else {
// Store the last selection
lastSelection = arr[minIdx];
if (minIdx != i) {
int temp = arr[minIdx];
arr[minIdx] = arr[i];
arr[i] = temp;
}
}
}
}
I think there is no name for this special sorting method.

Generation of 4 non repeating random numbers using arrays in java

I have this array
int [] marc = new int[4];
i need to insert a set of non repeating random numbers in the range of 1-10 to it
i'm using this for loop to set random numbers
for (he = 0; he < 4; he++) {
marc[he] = rn.nextInt(10 - 1 + 1) + 1;
marc[he]++;
}
it gives me random numbers but repeated ones inside the array
i'm also using
java.util.Random;
Well, yes, numbers can be repeated while being random. You need to do your own logic to validate if they're already on the array, this can be done with the following code:
In the code I used an array of 10 elements to observe there aren't repeated numbers even on that situation.
import java.util.Random;
public class RandomNumbersNoRepeating {
public static void main(String[] args) {
int array[] = new int[10];
Random random = new Random();
//Fills the array
for (int i = 0; i < array.length; i++) {
boolean found = false;
int r = 0;
do {
found = false;
r = random.nextInt(10) + 1;
//Here we check if the number is not on the array yet
for (int j = 0; j < array.length; j++) {
if (array[j] == r) {
found = true;
break;
}
}
} while (found);
array[i] = r;
}
//Prints the array
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Another possible solution, as given in a comment could be to shuffle an array from 1-10, and get the first four numbers
Using java.util.Random; will generate repetitive numbers more often when your range is small, which in your case is only 10. There is no condition in your code that checks whether the generated random number already exists in your array or not.
Before inserting a generated number in to the array, you first need to check whether that number already exists in your array. If it does not, you insert that number in the array, otherwise you generate a next random number.

List of Non-Repeating Ints in Java? Assignment

I'm trying to create a list of 20 integers between 0 and 26 (so in the 1-25 range) that does not repeat as a part of an assignment. I thought I had it figured out, but the program keeps looping over and over without ever ending. Can anyone help me out?
import java.util.Random;
public class prog433a
{
public static void main(String args[])
{
Random r = new Random();
int[] list = new int[20];
for (int k = 0; k < list.length; k++)
{
boolean notADupe = false;
while (notADupe == false)
{
list[k] = r.nextInt(25) + 1;
for (int j = 0; j < list.length; j++)
{
if (list[j] == list [k] && j != k)
{
notADupe = true;
}
else
{
notADupe = false;
break;
}
}
System.out.println(list[k]);
}
}
}
}
EDIT: This is different from the other question because I am trying to figure out how to check for uniqueness using the methods that I am allowed to use in my assignment (essentially, the ones I'm already using in the code).
I think you've reversed the condition out there. Inside if, you should set notADup to false, rather than true. However, I would make the variable isDup instead, and change the while loop accordingly.
One more suggestion: instead of while (notADupe == false), you should just use while (!notADupe). Never compare boolean variables like that. It might surprise you at times.
So to solve your issue, just change your if-else block to:
if (list[j] == list [k] && j != k) {
notADupe = false;
break;
} else {
notADupe = true;
}
BTW, your solution is a bit complex. For every element, you are iterating over whole array to find duplicate. Rather I would suggest you to maintain a Set<Integer> storing the already seen numbers, and check in that every randomly generated number. If present, skip it and re-generate.
Pseudo code would look something like this:
arr = [] // Your list array, initialize to size 20
seen = [] // A Set
for i from 1 -> arr.length
num = rand.nextInt(25) + 1
while seen contains num
num = rand.nextInt(25) + 1
seen.add(num)
arr[i] = num

Declaring int[] Array without defining size?

This is my code:
int[] primes = new int[25];
for (int i = 2; i <= 100; i++)
{
for (int j = i; j > 0; j--)
{
int prime = i%j;
if (prime == 0)
{
if ((j == i) || (j == 1))
{
isPrime = true;
}
else
{
isPrime = false;
break;
}
}
}
if (isPrime == true){
primes[index] = i;
index++;
}
}
As you can see, I'm writing prime numbers into array. I counted all the prime numbers that are within range 2-100, so I set array size to 25.
But let's say that I wouldn't know there are 25 prime numbers. Is there a way to create an array (any type of array) without defining the size? I tried this:
int[] primes = new int[0];
But it crashed.
You can use List for unknown size of data (probably ArrayList will be the best solution for you).
No; an array's size must be declared ahead of time. Try taking a look at the different implementations of List or Vector.
If in the end you absolutely need an array, you may create an array from your List.
Lists are best for situations, when you don't know exact size of array. For example, you can use ArrayList.
You have to use List instead of an Array.
Compiler needs to know the size of an Array. When you define an Array like this.
int[] primes = new int[0];
It creates space for only 1 integer. So, when you write to primes[1], it creates segmentation fault signal and your program crashes.
As mentioned by others, you can use an ArrayList, and if you still need the output as an array, you can convert the ArrayList to array at the end (once you know the size of the array).
Arrays are meant for the situation when we know about the size and number of elements we are going to put inside.If we are not sure about the size then in that case Collection API of Java can help you out.
for example
List Interface implemented by ArrayList and Vector
ArrayList can extends its size 50% at runtime so this will solve your problem.Or else you can use Vector if your application dealing with thread safety.but avoid using Vector because It increases its size to double at runtime.
This code may help you.
public static void main(String[] args) {
boolean isPrime;
List<Integer> list = new ArrayList<Integer>();
for (int i = 2; i <= 100; i++)
{
isPrime = true;
for (int j = 2; j < i/2; j++)
{
int prime = i % j;
if (prime == 0)
{
isPrime = false;
break;
}
}
if (isPrime == true){
list.add(i);
}
}
// all the prime numbers
for(Iterator<Integer> iterator = list.iterator(); iterator.hasNext();){
System.out.print(iterator.next()+" ");
}
}

Java - Repeat Function for Specific Numbers

I am exceptionally new to programming, but I am working on improving my skills as a programmer. Recently, I gave myself the challenge to determine what multiples of a given number are made up of distinct digits. I have gotten most of it to work, but I still need to make the code apply for every number that is a multiple of the input one. The code I have working so far is as follows:
Integer numberA = 432143;
Integer numberB = numberA;
Integer[] digitArray = new Integer[numberA.toString().length()];
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i]==digitArray[j])) repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberB);
}
This will determine if the number is made up of distinct digits, and, if it is, print it out. I have spent quite a bit of time trying to make the rest of the code work, and this is what I've come up with:
Integer number = 1953824;
Integer numberA = number;
Integer numberB = numberA;
for (Integer numberC = number; numberC.toString().length() < 11;
numberC = numberC + number) {
Integer[] digitArray = new Integer[numberA.toString().length()];
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i]==digitArray[j])) repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberB);
}
}
I can't figure out why, but his just prints whatever the number is a bunch of times if it is made up of distinct digits, and leaves it blank if it is not. If anyone could tell me why this is occurring, or even tell me what I need to do to fix it, that would be superb. Remember, I am very new to programming, so please give a short explanation for any terms you use that are at all out of the ordinary. I am eager to learn, but I currently know very little. Thank you for your time, and I greatly appreciate any and all help you can give me.
You assign the value of numberA to numberB (which is the value of number) right before the for loop. After that, numberB is never modified or assigned to a new value, so for every pass through the for loop, you're simply printing the value of numberB, which is always 1953824 in this case.
There are several corrections that can be made to achieve the result you desire, while cleaning up the code a little. The first thing is to change the print statement to print the correct number:
System.out.println(numberC);
Since numberC is the variable that is being updated by the for loop, that's what you'll want to conditionally print out if there are no repeat digits. Since we've replaced numberB with numberC, that means numberB is not longer needed, you can delete the declaration for it.
Now, the next issue is when you're defining the digital array - you should use the length of numberC, not numberA. Also, inside the for loop, you should assign numberA the value of numberC, or else eventually nothing but 0s will be stored in your digitArray. Overall, here's what it should look like.
Integer number = 1953824;
Integer numberA = number;
for (Integer numberC = number; numberC.toString().length() < 11;
numberC = numberC + number) {
Integer[] digitArray = new Integer[numberC.toString().length()];
numberA = numberC;
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i] == digitArray[j]))
repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberC);
}
}
This should produce the desired result. It seems to work on my machine :)
If you want, you can take Jeffrey's suggestion and change the Integer to the primitive int to avoid the overhead of boxing. However, you still need to use the Integer class to use the toString() method, but you can accomplish that using Integer.valueOf():
Integer.valueOf(numberC).toString()
So if I understand correctly you are trying to find out if certain multiple exists within your number. Instead of constantly dividing by 10 instead use the modulus symbol. You can even embed it in conditional statements.
For example:
if(numberOne % 2 == 0)
Then we know that numberOne divided by 2 has a remainder of zero and is thus a multiple of 2

Categories

Resources