Array Index assignment error with UserInput as If-Else conditional - java

I am getting an error and I cant quite understand the cause. I'm trying to get user-input using the Scanner method to assign values to the indices of an array, numbers. The user is allowed to keep - continue - entering values into the array numbers, however, if the user decides to stop, entering 0 will break the assignment of array-index values.
int[] numbers = new int[100];
int[] countIndex = new int[100];
int[] numberOcc = new int[100];
for (int i = 0; i < countIndex.length; i++)
{
countIndex[i] = i;
}
System.out.println("Enter your integer values: ");
for (int i = 0; i < numbers.length; i++)
{
if(input.nextInt() == 0)
{
break;
}
else
{
numbers[i] = input.nextInt();
}
}
This piece of code is a small part of a much larger code, however, it is very important. The error I'm getting is that the code is allowing the user to enter twice before moving to the next index, but the first integer entered it always skipped:
Enter your integer values:
1
2
0
0 occurs 99 times
2 occurs 1 time
UPDATES
System.out.println("Enter your integer values: ");
for (int i = 0; i < numbers.length; i++)
{
numbers[i] = input.nextInt();
if(numbers[i] == 0)
{
break;
}
}
Why is it that the 1 is ignored as input?
Also, is using input.nextInt() as the condition of an if-else statement bad code design?

From the comments
However, a 0 is still being placed in the index,
By default, int values will be assigned 0. So when you don't assign non zero values to int, they will still be 0.
One way around that is to use arraylist. Then once you enter all the numbers, you can convert arraylist to array.
Simple example without any input validation
List<Integer> list = new ArrayList<Integer>();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] defaultArray = new int[n];
// do validation for n
//assume n = 5 with values 1,2,0,3,2
for (int i = 0; i < n; i++) {
int temp = in.nextInt();
if (temp != 0) {
list.add(temp);
defaultArray[i] = temp;
}
}
Integer[] positiveArray = new Integer[list.size()];
positiveArray = list.toArray(positiveArray);
System.out.println(Arrays.toString(defaultArray)); //will print [1, 2, 0, 3, 2]
System.out.println(Arrays.toString(positiveArray)); //will print [1, 2, 3, 2]
If you want to convert Integer arraylist to int array, just search on google and there are many similar questions.
Demo

Related

Can someone explain me this code? About user input, scanner etc

Can someone explain to me how this code works?
It lets the user input numbers up until 1000, then it prints the original inputted numbers, the even and the odd, all in a separate array. But I just don't understand the parts where there is gem++ and gem1++ when it outputs the even and odd not the number of the even and odd numbers.
And after putting this
double even[] = new double[gem];
double odd[] = new double [gem1];
why does it need to repeat gem=0 and gem1=0 again? I'm so sorry if I ask too many question, I'm just confused, I just learned java last week.
public class wutt {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array : ");
int n = s.nextInt();
if (1 <= n && n <= 1000) {
double a[] = new double[n];
int gem = 0, gem1 = 0;
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
if (a[i] % 2 == 0)
gem++;
else
gem1++;
}
double even[] = new double[gem];
double odd[] = new double[gem1];
gem = 0;
gem1 = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] % 2 == 0) {
even[gem] = a[i];
gem++;
} else {
odd[gem1] = a[i];
gem1++;
}
}
System.out.println("Original: " + Arrays.toString(a));
System.out.println("Odd: " + Arrays.toString(odd));
System.out.println("Even: " + Arrays.toString(even));
} else
System.out.print("Invalid input");
}
}
If you want the program stops after the user enters a number greater than 1000 o less than 0 you need to add the break statement in your if condition.
if (size < 0 || size > 1000) {
System.out.println("Size must be between 0 and 1000");
break;
}
the code before double even[] = new double[gem];
double odd[] = new double [gem1]; is trying to get the number of odds occurred and the number of even occurred and put all inputted elements in array a.
after all that ,now what we got is a array of numbers called a containing all the inputted elements. and two numbers called gem and gem1, which contains the number of odds occurred and the number of even occurred.
so
we get gem(numberOfEvens), gem1(numberOfOdds) and list a
next, we need to put all odds from a to a new array called odd[] with size gem1, and
put all evens from a to a new array called even[] with size gem. at this point, the duty of variable gem1 and gem is done. they become useless.
now we need to go through the list and pick the odd and even out and put them in the array one by one in a sequential way. that's why we need two new variables with 0 initialized.
in this case, because gem and gem1 are useless aready, they are reassigned to help manipulate the tree arrays a , odd[] and even[]
So the user inputs the number of elements he/she wants in the array (n)
double a[] = new double[n]; // a is the array that is initialised to accommodate n elements
int gem = 0, gem1 = 0; // gem is the counter for "even" numbers and "gem1" the counter for odd numbers, and like every good counter, they start at 0
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) { // so we ask the user to input n elements
a[i] = s.nextInt(); // here we read every input and put it in the a array
if (a[i] % 2 == 0) // if the new number is even
gem++; // we increase the even counter "gem"
else // otherwise, when it is an odd number
gem1++; // we increase the odd counter
}
double even[] = new double[gem]; // now we create a new array where we want to hold all the even numbers, we do that by telling it how many even numbers we have counted before (gem)
double odd[] = new double[gem1]; // and a new array for all odd numbers (gem1 was our counter)
gem = 0; // now we reinitialise the counters, because we want to start from the beginning
gem1 = 0;
for (int i = 0; i < a.length; i++) { // in order to copy all numbers from the a array into the two other arrays for even and odd numbers, we iterate over the whole length of the a array. i is the index for the "a" array
if (a[i] % 2 == 0) { // ever even number we encounter
even[gem] = a[i]; // we put in the even array
gem++; // while gem, the "even numbers counter" is our index for the "even" array
} else {
odd[gem1] = a[i]; // odd numbers are for the odd array
gem1++; // while the former "odd numbers counter" now serves as our "odd" array index
}
}
and that's pretty much it. First the user inputs all numbers in a single array and simply counts how many odd and how many even numbers where inputted,
then two new arrays are created, one for the even and one for the odd numbers and since we counted them, we know how big these two new arrays have to be.
And finally all numbers are again iterated over and put in their according array.
At the end you have 3 array, one that holds all numbers, one that holds the even numbers and one with only the odd numbers.
EDIT
here are a few minor changes you could make without changing the nature of that method:
double allNumbers[] = new double[n]; // "allNumbers" is way more specific than "a"
int oddCounter = 0; // "oddCounter" instead of "gem"
int evenCounter = 0; // numbers in variables like "gem1" is really bad practice, because numbers don't say anything about the nature of the variable
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
allNumbers[i] = s.nextInt();
if (allNumbers[i] % 2 == 0) {
evenCounter++;
} else {
oddCounter++;
}
}
// until here nothing changes but the names
double even[] = new double[evenCounter];
double odd[] = new double[oddCounter];
int oddIndex = 0; // and here we create new variables, instead of reusing old ones
int evenIndex = 0; // there is absolutely no performance gain in reusing primitives like this - it's just confusing
for (int i = 0; i < allNumbers.length; i++) {
if (allNumbers[i] % 2 == 0) {
even[evenIndex++] = allNumbers[i]; // the "++" can be done directly in the first expression. that's just to make it shorter.
} else {
odd[oddIndex++] = allNumbers[i]; // it is not more performant nor easier to read - just shorter
}
}
EDIT (again)
This is how the arrays look like, say when you enter 4 numbers:
gem = 0
gem1 = 0
n = 4 // user said 4
a = [ , , , ] // array a is empty but holds the space for 4 numbers
a = [1, , , ] // user enters 1
^
i=0
gem1 = 1 // 1 is an odd number -> gem1++
a = [1,4, , ] // user entered "4"
^
i=1
gem = 1 // 4 is an even number -> gem++
a = [1,4,2, ] // user entered "2"
^
i=2
gem = 2 // 24 is an even number -> gem++
a = [1,4,2,7] // user entered "7"
^
i=3
gem1 = 2 // 7 is an odd number -> gem1++
then we fill the other arrays
even = [ , ] // gem is 2, so we have 2 even numbers
odd = [ , ] // gem1 is 2, so we have 2 odd numbers
a = [1,4,2,7]
^
i=0
odd[1, ] // for i=0, a[i] is 1, which is an odd number
a = [1,4,2,7]
^
i=1
even = [4, ] // for i=1, a[i] is 4, which is an even number
a = [1,4,2,7]
^
i=2
even = [4,2] // for i=2, a[i] is 2, which is an even number
a = [1,4,2,7]
^
i=3
odd = [1,7] // for i=3, a[i] is 7, which is an odd number
and in the end you have
a = [1,4,2,7]
even = [4,2]
odd = [1,7]

Java Random Utility Generating Too Many 0's And Static Numbers

The line birthdays[j] = rnd.nextInt(365); seems to generate extra 0's in the int[] birthdays array. It also seems to add an EXTRA 0 into the array and generate static values depending on how many simulations I run and how many birthdays I generate. For instance, if I do 5 simulations and enter a 3 for the number of people in each simulation's "birthday pool" I always get an array of [0, 0, 289, 362].
Any help understanding the problem would be greatly appreciated.
public static void main(String[] args) {
System.out.println("Welcome to the birthday problem Simulator\n");
String userAnswer="";
Scanner stdIn = new Scanner(System.in);
do {
int [] userInput = promptAndRead(stdIn);
double probability = compute(userInput[0], userInput[1]);
// Print results
System.out.println("For a group of " + userInput[1] + " people, the probability");
System.out.print("that two people have the same birthday is\n");
System.out.println(probability);
System.out.print("\nDo you want to run another set of simulations(y/n)? :");
//eat or skip empty line
stdIn.nextLine();
userAnswer = stdIn.nextLine();
} while (userAnswer.equals("y"));
System.out.println("Goodbye!");
stdIn.close();
}
// Prompt user to provide the number of simulations and number of people and return them as an array
public static int[] promptAndRead(Scanner stdIn) {
int numberOfSimulations = 0;
while(numberOfSimulations < 1 || numberOfSimulations > 50000) {
System.out.println("Please Enter the number of simulations to do. (1 - 50000) ");
numberOfSimulations = stdIn.nextInt();
}
int sizeOfGroup = 0;
while(sizeOfGroup < 2 || sizeOfGroup > 365) {
System.out.println("Please Enter the size of the group of people. (2 - 365) ");
sizeOfGroup = stdIn.nextInt();
}
int[] simulationVariables = {numberOfSimulations, sizeOfGroup};
return simulationVariables;
}
// This is the method that actually does the calculations.
public static double compute(int numOfSims, int numOfPeeps) {
double numberOfSims = 0.0;
double simsWithCollisions = 0.0;
int matchingBirthdays = 0;
int[] birthdays = new int[numOfPeeps + 1];
int randomSeed = 0;
for(int i = 0; i < numOfSims; i++)
{
randomSeed++;
Random rnd = new Random(randomSeed);
birthdays = new int[numOfPeeps + 1];
matchingBirthdays = 0;
for(int j = 0; j < numOfPeeps; j++) {
birthdays[j] = rnd.nextInt(365);
Arrays.sort(birthdays);
}
for(int k = 0; k < numOfPeeps; k++) {
if(birthdays[k] == birthdays[k+1]) {
matchingBirthdays++;
}
}
if(matchingBirthdays > 0) {
simsWithCollisions = simsWithCollisions + 1;
}
}
numberOfSims = numOfSims;
double chance = (simsWithCollisions / numberOfSims);
return chance;
}
}
The line "birthdays[j] = rnd.nextInt(365);" seems to generate extra 0's in the int[] birthdays array.
Well, it doesn't. The array elements where zero to start with.
What that statement actually does is to generate a single random number (from 0 to 364) and assign it to one element of the array; i.e. the jth element. That is not what is required for your problem.
Now, we could fix your code for you, but that defeats the purpose of your homework. Instead I will give you a HINT:
The birthdays array is supposed to contain a COUNT of the number of people with a birthday on each day of the year. You have to COUNT them. One at a time.
Think about it ...
int arrays are by default initialized to 0 unless explicitly specified. Please see this Oracle tutorial about Arrays.
I found the problem myself. The issue was that having the "Arrays.sort(birthdays);" statement inside of a loop. That generated extra 0's.

Array Outofbounds exception

im getting a out of bounds error on line 57. any help is appreciated. the program takes 1 integer and creates and array with that many indexes. it then asks for more integers to fill it up. it then takes all the even numbers and places it into a second array with is then outputted.
run:
Enter the ammount of integers you will require.
10
Enter your integers:
1
Enter your integers:
2
Enter your integers:
3
Enter your integers:
4
Enter your integers:
5
Enter your integers:
6
Enter your integers:
7
Enter your integers:
8
Enter your integers:
9
Enter your integers:
0
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at AllEven.arrcheck2(AllEven.java:57)
at AllEven.main(AllEven.java:24)
Java Result: 1
BUILD SUCCESSFUL (total time: 4 seconds)
CODE
import java.util.*;
public class AllEven {
public static void main(String[] args) {
int read;
Scanner kybd = new Scanner(System.in);
System.out.println("Enter the ammount of integers you will require.");
read = kybd.nextInt();
int[] arr1 = new int[read];
int[] arr2;
int count = 0;
arrRead(arr1);
arrcheck(arr1);
arr2 = new int[count];
arrcheck2(arr1, arr2);
mainPrint(arr2);
}
public static int arrcheck(int[] arr1) {
int count = 0;
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] % 2 == 0) {
count++;
}
}
return count;
}
public static void arrRead(int[] arr1) {
Scanner kybd = new Scanner(System.in);
for (int i = 0; i < arr1.length; i++) {
System.out.println("Enter your integers: ");
arr1[i] = kybd.nextInt();
}
}
public static void arrcheck2(int[] arr1, int[] arr2) {
int j = 0;
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] % 2 == 0) {
arr2[j] = arr1[i];
j++;
}
}
}
public static void mainPrint(int[] arr2) {
for (int i = 0; i < arr2.length; i++) {
System.out.println("Printing Even Numbers.");
System.out.println(arr2[i]);
}
}
}
ok so thanks everyone who helped, But now after the integers have been inputted the program just finishes without displaying anything after.
You need to assign the return value of arrcheck invocation in count variable before creating arr2. Otherwise, you would create your arr2 with size 0.
Change: -
int count = 0;
arrRead(arr1);
arrcheck(arr1);
to: -
arrRead(arr1);
int count = arrcheck(arr1);
After brief look at the code I think your problem lies here:
int count = 0;
arrRead(arr1);
arrcheck(arr1);
arr2 = new int[count]; //array of size 0!
arrcheck2(arr1, arr2);
You are defining arr2 as a zero-length array:
int count = 0;
....
arr2 = new int[count];
Then, in arrcheck2 you have the line:
arr2[j] = arr1[i];
This will not work because arr2 has no length so you cannot put anything into it.
The size of arr2 is 0. so when you try to access a non existing index in it you get the exception.
You create an array with length 0.
arr2 = new int[count];
You should give it a length bigger than 0.
If you want it to be the same length as arr1 just do arr2 = new int[read];
You need to initialize arr2 to the same length as arr1. int count = read will fix the issue. Or you can remove count entirely and just use read when initializing the array.
read = kybd.nextInt();
int[] arr1 = new int[read];
int[] arr2;
int count = read;
arrRead(arr1);
arrcheck(arr1);
arr2 = new int[count];
For starters you have your arrcheck function returning a count and not doing anything with it. I suspect you meant to write something like this:
arrRead(arr1);
int count = arrcheck(arr1);
otherwise your next line:
arr2 = new int[count];
creates an array of size 0 which will cause array out of bounds as soon as it is accessed.
Also you spelled Amount wrong, I think the rest of the program should work with the above change.
You are not initializing your array int[] arr2. You should not use an array to populate even elements from the initial array because arrays require a determined size upon initialization -- you are better off using ArrayList and then conver it into an array once you know the definitive size, if you must.

I'm getting strange output from java program

I've some strange situation here and i thought that you may help me. I have an int array populated with numbers from 1 to 10. I want to generate random number from this array and save it to another int array. I used class Random to pick any number and since random throws 0 also i modify it like that ( so it throws numbers from 1 to 10 )
randNum = rand.nextInt(numbers.length-min+1)+min;
Following code makes sure that if it generates same random number, it skips it. Program is actually working and i'm getting in another array randomly positioned numbers from 1 to 10. That's what i wanted. But sometimes i'm missing one number from 1 - 10 AND iam Getting ZERO instead. Why??
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
int[] usednum = new int[10];
Random rand = new Random();
int randNum;
int min = 1;
for (int x = 0; x<numbers.length; x++) {
for (int i = 0; i<usednum.length; i++) {
randNum = rand.nextInt(numbers.length-min+1) + min;
for (int f = 0; f<usednum.length; f++) {
if (usednum[f] == randNum) {
break;
} else if (usednum[f] == 0) {
usednum[x] = randNum;
}
}
}
}
for (int c = 0; c<usednum.length; c++) {
System.out.println(usednum[c]);
}
You're inner-most for loop only checks if the current random number is in the usednum[] array. And the for loop immediately outer of that only checks 10 times total. It gives up too quickly because it only tries 10 random numbers. If all 10 are already used, nothing will get stored in that slot of usednum[] (thus it will be 0), try adding a while loop around that and get rid of the extraneous outer-most for loop:
for(int i = 0; i<usednum.length; i++) {
while(usednum[i]==0) {
randNum = rand.nextInt(numbers.length-min+1)+min;
for(int f = 0; f<usednum.length; f++) {
if(usednum[f] == randNum) {
break;
} //if
else if (usednum[f] == 0) {
usednum[i] = randNum;
}
}
}
}
Also note that the assignment is for usednum[i] = randNum;.
This is essentially replacing the middle for loop (the one that goes from i=0 to 9) with the while loop.
If your goal is simply to shuffle an array of numbers, try this instead:
Integer[] numbers = {1,2,3,4,5,6,7,8,9,10};
Collections.shuffle(Arrays.asList(numbers));
It will have the same effect. Unless you are completing a homework assignment that forces you to solve the issue in a more manual fashion, just make use of the standard Java libraries.
The shuffle method writes changes through to the underlying Integer array, thanks to the special type of List returned by Arrays.asList(...). Note you have to use an array of Integer not int (see Why does Collections.shuffle() fail for my array?).
You are generating used numbers through an entire pass, so it doesn't generate a zero is just fails to generate a value it should.
you have one for loop too much.
remove the loop with the i iterator and the program should do what you want.
Oh and remove the -min+1 from the random generator, -1+1=0
Your array usednum is consisted of zeros at the beginning. In some cases, your program doesn't change that initial value, but breaks before at the line:
if(usednum[f] == randNum)
and does that during all iterations with same value x. X increments and there goes your chance to change the zero value.
Edit - followed it and re-wrote it:
List<Integer> numbers = new LinkedList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
int[] usednum = new int[10];
Random rand = new Random();
int n = numbers.size();
for (int i = 0; i < n; i++) {
int randNum = rand.nextInt(numbers.size());
usednum[i]=numbers.get(randNum);
numbers.remove(randNum);
}
for (int c:usednum) {
System.out.println(c);
}
Actually, you are never using the content of the array numbers. Try changing the array to something like int[] numbers = { 10, 22, 23, 42, 53, 18, 7, 8, 93, 10 };. You will get similar output.
Jon Lin's answer describe why your code is not working but does not address this issue. I think you will want to change your code to something like:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] usednum = new int[10];
Random rand = new Random();
int selectedCount = 0;
while (selectedCount < numbers.length) {
int randNum = numbers[rand.nextInt(numbers.length)];
boolean contains = false;
for (int x = 0; x < selectedCount; x++) {
if (usednum[x] == randNum) {
contains = true;
break;
}
}
if (!contains) {
usednum[selectedCount] = randNum;
selectedCount++;
}
}
for (int c = 0; c < usednum.length; c++) {
System.out.println(usednum[c]);
}

This code keeps on returning 0 instead of increasing in size?

What I am trying to do is:
Prompt the user for a list size (e.g., N = 10,000). Create an ArrayList of the Integers from 1 to N, in random order.
This is what I have so far, but the list just returns the number 0 n times
System.out.print("Please enter a list size: ");
Scanner ST = new Scanner(System.in);
int n= ST.nextInt();
List<Integer> myList = new ArrayList<Integer>(n);
for ( int i = 1; i<(n+1); i++){
int k = 0;
k = k + 1;
myList.add(k);
}
Yes, because you're declaring k inside the loop. Just move
int k = 0;
to before the loop. Currently the "newly declared" variable will be assigned the value of 0 on the first line of each iteration of the loop; it will then be incremented to 1 on the next line. Then that value (1) will be boxed and the return value Integer.valueOf(1) will be added to the list. Then we go round again...
An alternative is to just use the loop index - potentially changing the loop to a rather more idiomatic style at the same time:
for (int i = 0; i < n; i++) {
myList.add(i + 1);
}

Categories

Resources