ArrayIndexOutOfBoundsException computing the average - java

I'm working on this book by Randall S. Fairman, 3D Astronomy with Java, having limited experience with Java myself. He uses this LineReader class instead of Scanner or anything to take user input. The exercise I'm stuck on asks you to use LineReader to get values for an array and find the average of the values in the array. This is what I came up with, doing my best, and it doesn't work. When I try to run it, it says
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Average.main(Average.java:10)
Code:
import ui.LineReader;
public class Average {
public static void main(String[] args) {
int average;
int sum = 0;
for (int j = 0; j < 5; j++) {
int i = LineReader.queryInt("Give me a number: ");
int [] M = new int [i];
sum = sum + M[i];
}
average = sum/5;
System.out.println("The average of those numbers is " +average);
}
}

You don't need the int[]M = new int[i]; line.
Just do sum += i;
Your updated code:
import ui.LineReader;
public class Average {
public static void main(String[] args) {
int average;
int sum = 0;
for (int j = 0; j < 5; j++) {
int i = LineReader.queryInt("Give me a number: ");
sum += i;
}
average = sum/5;
System.out.println("The average of those numbers is " +average);
}
}

Related

Program ignoring the last row in the file in calculation

I have a text file with data that looks like this (TestData.txt):
Name|Test1|Test2|Test3|Test4|Test5|Test6|Test7|Test8|Test9|Test10
John Smith|82|89|90|78|89|96|75|88|90|96
Jane Doe|90|92|93|90|89|84|97|91|87|91
Joseph Cruz|68|74|78|81|79|86|80|81|82|87
Suzanne Nguyen|79|83|85|89|81|79|86|92|87|88
Richard Perez|100|84|73|81|92|84|95|96|95|100
Ivan Dyer|77|91|90|75|97|94|76|89|90|92
Craig Palmer|91|84|98|89|82|75|78|96|100|97
Madeline Rogers|75|79|78|93|91|76|80|88|100|81
Chelsea Roxas|87|94|89|96|95|85|88|92|86|86
Jasper Bautista|100|83|93|100|98|97|96|97|97|98
Tyler Perez|82|89|90|78|89|96|75|88|90|96
My code parses the file and does some calculations with it.
However, in the method arrangeList() within which calls another method called getTestAvg() (calculates column means), the program ignores Tyler Perez's scores.
I noticed that the results I am getting were inaccurate so I went and printed the whole 2d array with all the test scores and the last column is nowhere to be found.
My entire code is below and I hope someone could point out what causes this.
I keep getting an IndexOutOfBounds error whenever I try to switch N (# of students) and M (# of tests) to see what happens. At first, I have 10 students and 10 tests, and all the calculations were correct, but when I added another student, the calculations became inaccurate.
I apologize in advance if my code isn't as well-designed as I'm not an experienced programmer.
import java.util.*;
import java.io.*;
public class TestAverages
{
private static int[] grades;
private static int[] testTotal;
private static int N;
private static double classTotal;
private static int M;
public static void main(String[] args) throws FileNotFoundException
{
File input = new File("TestData.txt");
Scanner in = new Scanner(input);
parseFile(in);
}
public static void parseFile(Scanner in) throws FileNotFoundException
{
TestAverages t = new TestAverages();
in.nextLine();
double total = 0.0;
ArrayList<Double> testScores = new ArrayList<Double>();
int index = 0;
while(in.hasNextLine())
{
String line = in.nextLine();
String[] data = line.split("\\|");
String name = data[0];
grades = new int[data.length - 1];
N = grades.length;
for(int i = 0; i < N; i++){
grades[i] = Integer.parseInt(data[i + 1]);
testScores.add((double)grades[i]);
}
System.out.println(name + "\t");
System.out.println("Student Average: " + t.getStudentAvg(grades) + "%\n");
total += t.getStudentAvg(grades);
M++;
}
t.arrangeList(testScores);
System.out.printf("\nClass Average: %.1f%%\n", t.getClassAvg(total));
}
public double getStudentAvg(int[] grades)
{
double total = 0.0;
double avg = 0.0;
int N = grades.length;
for(int i = 0; i < N; i++){
total += grades[i];}
avg = total / N;
return avg;
}
public double getClassAvg(double total)
{
double classAvg = total / M;
return classAvg;
}
public double[][] arrangeList(ArrayList testScores)
{
double[][] tests = new double[N][N];
int len = tests.length;
for(int i = 0; i < len; i++)
{
for(int j = 0; j < len; j++)
{
tests[i][j] = (Double) testScores.get(i*N + j);
}
}
for(int i = 0; i < len; i++)
{
double avg = getTestAvg(tests, i);
System.out.printf("\nTest " + (i + 1) + " Average: %.1f%%\n", avg);
}
return tests;
}
public double getTestAvg(double[][] testScores, int index)
{
double testAvg = 0.0;
for(int i = 0; i < N; i++)
{
testAvg += testScores[i][index];
}
return testAvg / N;
}
}
Here are the numbers I'm supposed to be getting (top) compared to what my program outputs (bottom).
As the other responses already stated, you had quite the issue with your variables and loops. I now changed N to # of students and M to # of tests to be as you stated in your question.
Next time, maybe try to improve your variable naming, so you don't get confused. (e.g. switch out n and m for s (students) and t (tests), if you like your variable names short).
This should work now. Just check against your code to see the changes.
import java.util.*;
import java.io.*;
public class TestAverages {
private static int[] grades;
private static int n = 0; // amount of students
private static int m; // amount of tests
public static void main(String[] args) throws FileNotFoundException {
File input = new File("TestData.txt");
Scanner in = new Scanner(input);
parseFile(in);
}
public static void parseFile(Scanner in) throws FileNotFoundException {
TestAverages t = new TestAverages();
in.nextLine();
double total = 0.0;
ArrayList<Double> testScores = new ArrayList<Double>();
while (in.hasNextLine()) {
String line = in.nextLine();
String[] data = line.split("\\|");
String name = data[0];
grades = new int[data.length - 1];
m = grades.length;
for (int i = 0; i < m; i++) {
grades[i] = Integer.parseInt(data[i + 1]);
testScores.add((double) grades[i]);
}
System.out.println(name + "\t");
System.out.println("Student Average: " + t.getStudentAvg(grades) + "%\n");
total += t.getStudentAvg(grades);
n++;
}
t.arrangeList(testScores);
System.out.printf("\nClass Average: %.1f%%\n", t.getClassAvg(total));
}
public double getStudentAvg(int[] grades) {
double total = 0.0;
double avg = 0.0;
for (int i = 0; i < grades.length; i++) {
total += grades[i];
}
avg = total / grades.length;
return avg;
}
public double getClassAvg(double total) {
double classAvg = total / n;
return classAvg;
}
public double[][] arrangeList(ArrayList<Double> testScores) {
double[][] tests = new double[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
tests[i][j] = (Double) testScores.get(i * m + j);
}
}
for (int i = 0; i < m; i++) {
double avg = getTestAvg(tests, i);
System.out.printf("\nTest " + (i + 1) + " Average: %.1f%%\n", avg);
}
return tests;
}
public double getTestAvg(double[][] testScores, int index) {
double testAvg = 0.0;
for (int i = 0; i < n; i++) {
testAvg += testScores[i][index];
}
return testAvg / n;
}
}
You need to account for the different sizes. I think you want primarily the number of TESTS (not students), but you can't just use len for both index bounds.
double[][] tests = new double[N][M];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
tests[i][j] = (Double) testScores.get(i*N + j);
}
}
Note that it didn't just resize the array, but it changed the loop conditions to loop the proper amount for inner and outer loop.
In the line
double[][] tests = new double[N][N];
of function arrangeList
you make your test array as N X N.
I believe youh should do something like
double[][] tests = new double[M][N];
It's just a suggestion as in your code it seems M = number of students and N = number of tests, differently from what you write in your question.
In general you should review all the method arrangeList and probably getTestAvg too (loop on N, instead of M), as the loops on variable len are intended for a N X N array, which is not the case.

create a program that prompts the user to enter a number between 1 and 15 and print the sum as shown: 1=1, 1+2=3, 1+2+3=6, 1+2+3+4=10

I seriously need help please
1=1, 1+2=3, 1+2+3=6, 1+2+3+4=10
I don't know how to code the equation part
import java.util.Scanner;
public class Equations {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println ("Enter a number between 1 to 15: ");
int num = scan.nextInt();
int total = 0;
int save;
for(int i=1;i<=num;i++)
{
for(int j=1;j<=num;j++)
{
save = total+i;
i++;
}
System.out.print (save+"="+total);
System.out.println ();
}
}
This is all I have, and it doesn't work.
There are quite a few things off. You're not resetting total or save after each equation. save is an int, so it can't hold the equation string. j needs to increment to i, not num. total is never incremented. i++ doesn't belong in the inner loop.
Here's a simple, correct version:
for (int i = 1; i <= num; i++) {
int sum = 0;
String equation = "";
for (int j = 1; j <= i; j++) {
sum += j;
equation += "+" + j;
}
System.out.println(equation.substring(1) + "=" + sum);
}

java: Birthday probability program

I'm trying to create a program that finds the probability of two random students in a room to have the same birthday. Number of students and number of simulations is inputted. Whenever I run it though, with 23 students, I consistently get 0.69, which is inconsistent with the actual answer of about 0.50. I think it probbaly has something to do with the fact that, if there are 3 students with the same birthday, it will count it as 3 matches. But I'm not sure how to fix this problem and I've already tried multiple times. Can I get some help?
import java.util.Scanner;
public class bday{
public static void main(String[] args){
Scanner inp = new Scanner(System.in);
System.out.println("How many students?");
int num = inp.nextInt();
System.out.println("How many times?");
int times = inp.nextInt();
double x[] = new double[num];
int match = 0;
for(int i=0;i<times;i++){
for(int j=0;j<num;j++){
x[j] = (int)(Math.random()*365)+1;
}
for(int j=0;j<num;j++){
for(int k=j+1;k<num;k++){
if(x[j]==x[k]){
match++;
}
}
}
}
double prob = (double)match/times;
System.out.println("The probability for two students to share a birthday is "+prob+".");
}}
You messed up the logic. The logic should be like this:
whenever there is a occurrence of same birthday, you add one to the total matches and then break then start another time. After you finished all the times, divide the total matches by how many times.
here is the code:
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
Scanner inp = new Scanner(System. in );
System.out.println("How many students?");
int num = inp.nextInt();
System.out.println("How many times?");
int times = inp.nextInt();
int x[] = new int[num];
int matches = 0;
boolean out = false;
for (int i = 0; i < times; i++) {
for (int j = 0; j < num; j++) {
x[j] = (int)(Math.random() * 365) + 1;
}
for (int j = 0; j < num; j++) {
for (int k = j + 1; k < num; k++) {
if (x[j] == x[k]) {
matches++;
out = true;
break;
}
}
if (out) {
out = false;
break;
}
}
}
double prob = (double) matches / times;
System.out.println("The probability for two students to share a birthday is " + prob + ".");
}
}
The test result: 0.50557 for 100000, 0.507591 for 1000000. Should be close to your answer.

Nested for loop sum of integers

public class NestedCountLoop
{
public static void main(String[] args)
{
int sum = 0;
for (int i = 1; sum < 5050; i++) {
sum = sum + i;
System.out.println(sum);
}
}
}
So I have a little homework assignment for my intro programming class to use a nested loop to accept positive integer input and add all of the integers within the interval from 1 to that input. My mind is playing games with me and I'm having trouble getting going. I know I need a scanner and whatnot, and it has to print every result from 1 to n such as "The sum of 1 to 100 is 5050." Any advice is helpful
Information on scanner at from http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
Scanner sc = new Scanner(System.in);
for (int i = o; i < 100; i++){
int upperLimit = sc.nextInt();
for (int w = 0; w < upperLimit; w++){
sum = sum + i;
}
System.out.println("Sum is " + sum);
}
public class NestedCountLoop
{
public static void main(String[] args)
{
int to = Integer.parseInt(args[0]);
int sum = 0;
for (int i = 1; sum < to; i++) {
sum = sum + i;
System.out.println(sum);
}
}
}
How about this one? It takes an input from the command line (arg0), and adds every number to your number (not inclusive).
So you have to compile your java file with javac, then you can run:
javac NestedCountLoop.java
java NestedCountLoop.class 100
On the other hand, the a previous solution mentioned the javadoc for your scanner, if you really need to use it. :)
System.out.println("Enter your maximum number: ");
// get the input
Scanner input = new Scanner(System.in);
int max = input.nextInt();
int sum = 0;
// iterate through an array to sum up the numbers
for (int i = 1; i < max; i++) {
sum = sum + i; // sum += i;
}
// print out the sum after you counted everything
System.out.println(sum);
import java.util.Scanner;
public class sumoftenIntegerInput {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int sum = 0;
for(int i=1; i<=10; i++){
System.out.println("Enter integer input " + i + ":");
int a = input.nextInt();
sum = sum + a ;
}
System.out.println("Total is:" + sum );
}
}

Write an object oriented program that randomly generates an array of 1000 integers between 1 to 1000

this code doesn't function,
it said that lessthaAverage(int) in calculateArray cannot be applied to (), I'm a beginner so I still don't understand this coding yet, this is the question ask, Write an object oriented program that randomly generates an array of 1000 integers between 1 to 1000.
Calculate the occurrences of number more than 500 and find the average of the numbers.
Count the number which is less than the average and finally sort the numbers in descending order.
Display all your output. Please do HELP ME!!!,Thank You...
import java.util.*;
import java.io.*;
//import java.util.random;
public class CalculateArray
{
//declare attributes
private int arr[] = new int[1000];
int i;
//generates an array of 1000 integers between 1 to 1000
public void genArr()
{
Random ran = new Random();
for(i = 0; i < arr.length; i++)
{
arr[i] = ran.nextInt(1000) + 1;
}
}
//Calculate the occurences of number more than 500
public int occNumb()
{
int count;
for(i = 0; i < arr.length; i++)
{
if(arr[i] > 500)
{
count++;
}
}
return count;
}
//find the average of the numbers
public int average()
{
int sum, aver;
for(i = 0; i < arr.length; i++)
{
sum += arr[i];
}
aver = sum/1000;
return aver;
}
//Count the number which is less than the average
public int lessthanAverage(int aver)
{
int cnt;
cnt = 0;
for(i = 0; i < arr.length; i++)
{
if(arr[i] < aver)
{
cnt++;
}
}
return cnt;
}
//finally sort the numbers in descending order.
public void sort(int[] num)
{
System.out.println("Numbers in Descending Order:" );
for (int i=0; i <= num.length; i++)
for (int x=1; x <= num.length; x++)
if (num[x] > num[x+1])
{
int temp = num[x];
num[x] = num[x+1];
num[x+1] = temp;
}
}
//Display all your output
public void display()
{
int count, aver;
System.out.println(arr[i] + " ");
System.out.println("Found " + count + " values greater than 500");
System.out.println("The average of the numbers is " + aver);
System.out.println("Found " + count + " values that less than average number ");
}
public static void main(String[] args)
{
CalculateArray show = new CalculateArray();
show.genArr();
int c= show.occNumb();
show.average();
int d=show.lessthanAverage();
show.sort(arr);
show.display();
}
}
Your method lessthanAverage is expecting a int parameter. You should store the result of the average method call into a int variable and pass it to the call to lessthanAverage.
int avg = show.average();
int d=show.lessthanAverage(avg);
Your lessthaAverage() method expects an average to be passed in as a parameter, but you are not passing it in when you call it.
It seems that your method lessthanAverage needs an int as a parameter, but you are not passing it in main
public int lessthanAverage(int aver)
In main aver is not being passed:
int d=show.lessthanAverage(); // where is aver?
But if you wanted to know the average inside the method you could call your average method inside lessthanAverage:
if(arr[i] < this.average())
and not pass any parameter at all:
public int lessthanAverage()

Categories