Array keeps counting 0 as a number when I didn' - java

I'm trying to make a game show program where I enter the number of contestants, how fast they hit the buzzer, the fastest and slowest times for hitting the buzzer, and the number of people that hit the buzzer faster than average.
Everything goes well with my program when I have 5 contestants. But if I enter 4 contestants or anything else less than 5, it messes up some things. When I have 4 contestants, my fastest time is 0, even when I'm not putting in a 0 as a time, and the number of contestants that hit the buzzer faster than average is also messed up, having one extra than it should, because it's putting in a 0.
How do I stop this program from adding in a 0 when I don't have 5 contestants?
import java.util.Scanner;
public class FastestFingers {
public static void main(String[] args) {
//declare varialbes
int contestants;
int [] milisecs = new int [6];
int fastest, slowest, i;
int faster = 0;
double average;
Scanner scanInt = new Scanner (System.in);
//make user enter number of contestants
System.out.println ("Enter # of contestants: ");
contestants = scanInt.nextInt();
//make user enter times
for(i=1;i<=contestants;i++)
{
System.out.println ("Time (ms): ");
milisecs[i] = scanInt.nextInt();
}
//calculate fastest time
fastest = milisecs[1];
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i] < fastest)
{
fastest = milisecs[i];
}
}
System.out.println ("Fastest: " + fastest);
//calculate slowest time
slowest = milisecs[1];
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i] > slowest)
{
slowest = milisecs[i];
}
}
System.out.println ("Slowest: " + slowest);
//tell program how to find average
int total = 0;
for(i=1;i<milisecs.length;i++)
{
total = total + milisecs[i];
}
average = total/contestants;
//find numbers faster than the average
int count = 0;
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i]<average)
{
count++;
}
}
System.out.println ("Faster than average: " + count);
}
}

You create an int[] of fixed size 6. Then you compare the last 5 values to find the lowest. All int values are default 0. If you only set 4 values to anything larger than 0 the fifth value will always be 0 and therefore your lowest value.
You can fix this problem by setting the size of your array to the number of contestants.
Also remember that arrays start counting at 0 not at 1. Your loops should therefore be:
for(i=0;i<milisecs.length;i++), etc.

The problem is that you initialize the array to have six elements.
int [] milisecs = new int [6];
By default all of these values will be zero. Then in your loop you only initialize four of them, meaning that two will still be zero. Change your code to:
System.out.println ("Enter # of contestants: ");
contestants = scanInt.nextInt();
int [] milisecs = new int [contestants];
This will ensure that you will only have as many time slots as you have contestants.
Also array indexes start at zero, so you should change
fastest = milisecs[1];
to
fastest = milisecs[0];
And in your loops, start your variable at 0 instead of 1.

Array Index should start with 0. Please be careful with this. You code reads input and assigns to the milisecs starting from index 1.

Related

print entered integer from input integer to integer

I am trying to obtain two integers as input, and then use these to output another list of integers, using the input as arguments in a loop.
In my code, if I enter low as 1, and high as 10 I expect my output should be the integers 1 through 10. However my code prints the value 1 ten times. I have tried different loops with no luck. Can someone please point out why my output is not as expected?
import java.util.Scanner;
public class test1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the low number: ");
int low = input.nextInt();
System.out.print("Enter the high number: ");
int high = input.nextInt();
//int num1 = low
//int num2 = high
System.out.println("Decimal");
for(int i = low ; low <= high; low++)
System.out.println(i);
}
}
So the issue is that in your for loop you are incrementing the value of low with low++ but you're printing i which you only set to the value of low at the beginning; i doesn't get reset to the value of low on every iteration in your for loop.
So, try changing low++ to i++ and see if that makes a difference ;)
You'll also want to change low <= high to i <= high as we are now incrementing i.

Java, can't find average of an array

I need to write a program that finds an average of all values in the array and then returns ones larger than the average.
import java.util.*;
public class AboveAverage {
public static void main(String args[]) throws Exception {
Scanner kbd = new Scanner(System.in);
int count=0, num;
int nums[] = new int[1000];
double sum = 0;
double average = 0;
System.out.println("Input +ve integers, to stop type 0");
num = kbd.nextInt();
while( num > 0 ) {
nums[count] = num;
count = count + 1;
num = kbd.nextInt();
}
int d = 0;
while ( d < 1000 ) {
sum += nums[d];
d++;
average = sum / nums[d];
}
for(int i=0; i < count ; i=i+1) {
System.out.print(nums[i] + " ");
}
System.out.println(average);
}
}
In my opinion problem is in this line
I tried the one below which gives an exception
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1000
at AboveAvarage.main(AboveAvarage.java:23)
average = sum / nums[d];
I also tried
average = sum / nums.length;
Which gave me the sum instead of the average.
Remember that array indices in Java go from zero? This means the allowed indices in your nums array are 0 through 999.
Now look at this loop:
int d = 0;
while ( d < 1000 ) {
sum += nums[d];
d++;
average = sum / nums[d];
}
First, it adds the current number to the sum. This is correct.
Then, it increments the number.
Then it uses the incremented number to access nums[d] to calculate the average.
Now, imagine that you are at the last round. d is 999.
First, it adds the current number to the sum.
Then it increments d. Now it is 1000.
Then it uses the incremented number to access nums[d]. But this means nums[1000]. And that's an illegal index.
So this explains why you have an ArrayIndexOutOfBoundsException. You should never use the index again after you incremented it, because the while only guaranteed that its previous value was less than 1000. If you change the value, you need to test again. This is why normally the increment step is the last in the loop.
As for your logic:
To calculate an average, you first need to know the sum. After you know the sum, you can divide by the number of items you are averaging. So you need to divide the sum by the number of items you read.
So:
You should not do a loop up to 1000. If you entered 0 after 5 numbers when you inputted the data, then there will be no values in the rest of the array (or rather, there will be zeros there).
You can calculate the sum, as another answer told you, in the first loop. No need to do that in the second loop.
You don't calculate the sum and the average in the same step. You first have to complete calculating the sum (finish the loop, be it the first or the second), and only then you can divide by the number of items (which you saved in count).
Then you have to go through another loop, that prints the numbers that are larger than the average. Your print loop prints all the numbers. You should check each number, see if it is greater than the average you calculated, and only if it is, print it.
Hint: there should really only be two loops: One that reads the numbers and calculates the count and the sum. Then you calculate the average, but that's not a repeating action, so it should not be in a loop. The second loop is for printing the numbers that are above average.
In the while loop that is gathering values, you are using count to track how many values are provided.
In the subsequent loop to calculate the average, you should only look at count items of the array:
int d = 0;
while(d<count) {
sum += nums[d];
}
average = sum/count;
Note you don't need to calculate average within the loop - do it once you've summed the values.
You don't need the other while loop, add up sum upon input. When done, just divide by count
while( num > 0 ) {
nums[count] = num;
count = count + 1;
sum += num;
num = kbd.nextInt();
}
average = sum / count;

Rolling m die with n sides x times

Okay so I changed my code around and deleted a lot of the unnecessary garbage in it. It works for some numbers but not for others, for example, when I put in 100 rolls/8 sides/3 die it gives me an out of bounds error despite the limits I've set for it. Obviously I've looked over some detail, I'm just not sure what detail it is.
public class Ass11f {
public static void main(String[] args) {
EasyReader console = new EasyReader();
System.out.print("Enter how many times you want to roll the die: ");
int numRolls = console.readInt();
System.out.print("Enter the amount of sides: ");
int numSides = console.readInt();
System.out.print("Enter the amount of die: ");
int numDie = console.readInt();
int[] rollSum = new int[numDie*numSides];
for (int i = 0; i<numRolls; ++i)
{
int rollCounter=0;
for (int l = 0; l<numDie; ++l){
rollCounter += ((int)(Math.random()*numSides)+1);
}
rollSum[rollCounter]++;
}
for (int m = 2;m<=rollSum.length;++m) System.out.println(m+"'s: "+rollSum[m]+" times, "+((((double)rollSum[m])/numRolls)*100)+"%");
}
}
There are two base problems:
When adding roll totals, you're trying to add the maximum roll in an index one past the end of the array. The easy fix is to simply add 1 to the length of your array.
When printing, you cannot access an array using an index equal to the array's length, which is what m<=rollSum.length will eventually do. Replace that with m < rollSum.length so it stops before the final value.
Also, here's some ways to make your array creation a bit clearer:
// The minimum value is always numDie.
// The maximum is always numDie * numSides
// There are maximum - minimum + 1 possible values (ie 6 on a d6)
int maximum = numDie * numSides;
int minimum = numDie;
// Remember, index zero is now the minimum roll.
// The final index is the maximum roll. So the count at an index is really
// the count for any roll with value index + minimum
int[] rollSum = new int[maximum - minimum + 1];
I also recommend splitting up that print statement. It's a bit easier to read and debug. Also, you can start at numDie instead of 2 to account for when you have more or less die than 3:
for (int i = numDie; i < rollSum.length; ++i) {
// Print the first bit, ie "2's: ".
System.out.print(i + "'s: ");
// How many times was that value rolled?
System.out.print(rollSum[i] + " times, ");
// What percentage is that?
double percentage = ((double)rollSum[i]) / numRolls * 100;
System.out.println(percentage + "%");
}

Java While loop skipping lines, doing them every 2 cycles instead

I'm writing a program for homework that is supposed to read in an unspecified number of 0-100 scores (maximum of 100 scores) and stop after -1 or any negative number is entered.
I've put this into a Do While loop that is set to terminate when -1 is pulled in through Scanner. The loop has a counter that keeps track of how many times the loop has been gone through, an adder that adds all the input lines together to later compute an average, and a means to send the input value to an array after it has checked to see if the number is -1.
Instead of doing this, the loop only increments the counter every 2 loops and -1 will only terminate the loop on an even cycle number, other wise it will wait until the next cycle to terminate. This completely baffles me, I have no idea why it's doing this. Could someone point out the error? Thanks in advance! This is all I have so far.
import java.util.Scanner;
public class main {
//Assignment 2, Problem 2
//Reads in an unspecified number of scores, stopping at -1. Calculates the average and
//prints out number of scores below the average.
public static void main(String[] args) {
//Declaration
int Counter = 0; //Counts how many scores are
int Total = 0; //Adds all the input together
int[] Scores = new int[100]; //Scores go here after being checked
int CurrentInput = 0; //Scanner goes here, checked for negative, then added to Scores
Scanner In = new Scanner(System.in);
do {
System.out.println("Please input test scores: ");
System.out.println("Counter = " + Counter);
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += In.nextInt();
Counter++;
} while ( CurrentInput > 0);
for(int i = 0; i < Counter; i++) {
System.out.println(Scores[i]);
}
System.out.println("Total = " + Total);
In.close();
}
}
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += In.nextInt();
You are calling twice In.nextInt(), i.e., you are reading two lines in each loop iteration.
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += CurrentInput;
Use this instead.

Taking average of user input number

This is my code
import java.util.*;
import java.io.*;
public class eCheck10A
{
public static void main(String[] args)
{
PrintStream out = System.out;
Scanner in = new Scanner(System.in);
out.print("Enter your integers");
out.println("Negative = sentinel");
List<Integer> aList = new ArrayList<Integer>();
for (int n1 = in.nextInt(); n1 > 0; n1 = in.nextInt())
{
if(n1 < 0)
{
break;
}
}
}
}
if i want to take all the numbers that I enter for n1, and average them out, how do i refer to all these numbers? I am going to put them in the IF statement, so if a negative number is entered, the program stops and posts their average.
This is the pseudocode you need to do this task (pseudo-code since it looks suspiciously like homework/classwork and you'll become a better developer if you nut out the implementation yourself).
Because you don't need the numbers themselves to work out the average, there's no point in storing them. The average is defined as the sum of all numbers divided by their count, so that's all you need to remember. Something like this should suffice:
total = 0
count = 0
n1 = get_next_number()
while n1 >= 0:
total = total + n1
count = count + 1
n1 = get_next_number()
if count == 0:
print "No numbers were entered.
else:
print "Average is ", (total / count)
A couple of other points I'll mention. As it stands now, your for statement will exit at the first non-positive number (<= 0), making the if superfluous.
In addition, you probably want any zeros to be included in the average: the average of {1,2,3} = 2 is not the same as the average of {1,2,3,0,0,0} = 1.
You can do this in the for statement itself with something like:
for (int n1 = in.nextInt(); n1 >= 0; n1 = in.nextInt())
and then you don't need the if/break bit inside the loop at all, similar to my provided pseudo-code.
An outline of what you will need to do: Create a variable sum to add up all of the values and create another variable called count that will be used to store the number of non-negative numbers in your list, aList. Then divide the sum by the count to find the average.
Another way to do running average is:
new_average = old_average + (new_number - old_average ) / count
If you ever hit max for a variable type, you would appreciate this formula.

Categories