How would I calculate the average in a 2D Array? - java

To start, I'm not completely new to Java and I have taken a course on it. Recently, I picked it up a again after a year and I'm a bit confused as to how to calculate an average in a 2D array of integers. For example, here's an excerpt of code not including the average calculation:
//Program fills array with x students and their corresponding test grades for n amount of tests
System.out.println("Amount of students?");
int numstudents = sc.nextInt();
System.out.println("Amount of tests?");
int numtests = sc.nextInt();
int[][] marks = new int [numstudents][numtests];
int[] average = new int [numstudents];
for (int i = 0; i < numstudents; i++) {
for (int j = 0; j < numtests; j++) {
System.out.println("Enter the mark for student " + (i+1) + " on test " + (j+1));
marks[i][j] = sc.nextInt();
//Array is filled with grades.
}
}
Now let's say I wanted to calculate the average for each student and store the values in the average[] array. My main problem is figuring out how to loop it so that it includes every test for marks[0][j] and then moves on to marks[1][j] and so on. If I do something like the code below, it takes each test value and divides it by numtests.
for (int i = 0; i < numstudents; i++) {
for (int j = 0; j < numtests; j++) {
average[i] = marks[i][j]/numtests;
System.out.println("The average is " + average[i]);
}
}

I think average[i] should be calculated
for (int i = 0; i < numstudents; i++) {
//here
for (int j = 0; j < numtests; j++) {
}
How about writing codes like as follows?
int eachsum = 0;
for (int i = 0; i < numstudents; i++) {
for (int j = 0; j < numtests; j++) {
eachsum += marks[i][j];
}
average[i] = eachsum/numtests;
System.out.println("The average for student " + (i+1) + " is " + average[i]);
eachsum = 0;
}

You can do the following:
int[] average = Arrays.stream(marks)
.map(ints -> Arrays.stream(ints).summaryStatistics().getAverage())
.mapToLong(Math::round)
.mapToInt(Math::toIntExact)
.toArray();
Input:
int[][] marks = {
{80, 70 ,90},
{90, 65 ,90},
{50, 70 ,70},
{80, 75 ,85}
};
Output:
[80,
82,
63,
80]

Related

How to sum + average of results from values taken from an array of values given by user

After adding 2 for loops – one to take values from user for rows and columns and another for print – I cannot figure out how to sum and give average after.
Write a program that allows a user to enter 5 results for each year of a 4 year course.
The app should:
Give an average for each year
Give a total average
import javax.swing.JOptionPane;
public class YearlyResult {
public static void main(String[] args) {
//declare variables
String[] year = {"Year 1","Year 2","Year 3","Year 4"};
int rows = year.length;
int numLectures = 5;
int columns = numLectures;
double sum;
double[][] results;
results = new double[rows][columns];
//input
for(int i = 0; i < rows; i++) {
for(int j = 0; j < columns; j++) {
results[i][j] = Double.parseDouble(JOptionPane.showInputDialog(null,"Please enter result "+(j+1)+"for"+year[i]));
}
}
//output
for(int i = 0; i < rows; i++) {
for(int j = 0; j < columns; j++) {
System.out.println(year[i] + " result #"+(j+1)+" is: " + results[i][j]);
}
for(int j = 0; j < columns; j++) {
sum = results[0][0];
System.out.println("Total Yearly result" + sum*numLectures);
}
System.out.println("------------------");
}
}
}
var sums = new double[results.length];
var avgs = new double[results.length];
for(var i=0; i < results.length; i++) {
for(var j=0; j < results[i].length; j++) {
sums[i] = sums[i] + results[i][j];
}
avgs[i] = sums[i] / results[i].length;
}
This should (typed on mobile) should give you sum and average per row. The same way you can iterate over sums and avgs to get the overall values.
Would be much more elegant to use Java Stream API, but I think that’s beyond scope of this lesson.

How to get the sum for each row?

I want to find and display the row number that has the maximum sum and display the row values and this is sample input/output:
The problem is every time the maximum sum is the third row how to solve these issues.
int [][] scores = new int[4][3];
for (int i=0; i<scores.length; i++)
{
System.out.print("Enter values for row "+i+": ");
for (int j=0; j<scores[i].length;j++)
scores[i][j] = kbd.nextInt();
}
int sum, sumMax, ii=0;
for (int i=0; i<scores.length; i++)
{
sum =0; sumMax = 0; ii=0;
for (int j=0; j<scores[i].length;j++)
{
sum += scores[i][j];
if (sum>sumMax)
{
sumMax = sum;
ii = i;
}
}
}
System.out.println("Row "+ii+" has the maximum sum");
System.out.print("Row "+ii+" has the following values: ");
for (int j = 0; j < 3; j++)
System.out.print(scores[ii][j] + " ");
To print a specific row, you need one loop only
System.out.print("Row " + ii + " has the following values: ");
for (int j = 0; j < 3; j++)
System.out.print(scores[ii][j] + " ");
Or with Arrays.toString
System.out.println("Row " + ii + " has the following values: " + Arrays.toString(scores[ii]));
Also your finding max code is wrong, as you reset ii and sumMax to 0 for each row, the max can only be the last line, you need to keep track of these 2 along the rows. Also use the if only after computing the row's sum, no need to test at every bow of every row
int sum, sumMax = Integer.MIN_VALUE, ii = 0;
for (int i = 0; i < scores.length; i++) {
sum = 0;
for (int j = 0; j < scores[i].length; j++) {
sum += scores[i][j];
}
if (sum > sumMax) {
sumMax = sum;
ii = i;
}
}
You can add the rows while getting the input from scanner and store them in an array. Then you can search for the max value in the sums array:
import java.util.Scanner;
public class Example {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
int[][] scores = new int[4][3];
int[] rowSums = new int[4];
for (int i = 0; i < scores.length; i++) {
System.out.print("Enter values for row " + i + ": ");
for (int j = 0; j < scores[i].length; j++){
scores[i][j] = kbd.nextInt();
rowSums[i] += scores[i][j];
}
}
int index = 0;
int maxSum = rowSums[index];
for(int i = 1; i < rowSums.length; i++){
if(rowSums[i] > maxSum){
maxSum = rowSums[i];
index = i;
}
}
System.out.println("Row "+index+" has the maximum sum");
System.out.print("Row "+index+" has the following values: ");
for(int i = 0; i < scores[index].length; i++){
System.out.print(scores[index][i] + " ");
}
}
}

Sort 2D array by average value of each line

I have complex task to differently sort two dimensional array manually.
So far I get done those tasks:
User needs to input row size from 10 - 20,
Generate 2D array where row size is user input and column size is randomly generated from 10-50,
Each array is filled with randomly generated numbers from 100 - 999,
Output each array row by its descending value,
Output average value of each array line,
Output on screen array with biggest average value,
So far I can't solve task Nr. 7. Output sorted two dimensional array by each lines average value.
Tried to implement new arrayAverage in loop to sort lines it didn't work.
Array just need to be sorted without creating new array.
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class SortArray2D {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Sorting two dimensional arrays!!!");
System.out.print("Enter arrays 1st dimension size 10 - 20: ");
int array1stDsize = sc.nextInt();
int array2ndDsize = new Random().nextInt(40) + 10;
System.out.println();
sc.close();
if (array1stDsize > 20 || array1stDsize < 10) {
System.out.println("The number you entered is too big or too small!!!");
} else {
//initializing array
int[][] array = new int[array1stDsize][array2ndDsize];
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
int input = new Random().nextInt(900) + 100;
array[i][j] = input;
}
}
System.out.println("Array element output: ");
arrayOutput(array);
// array element sorting from biggest to smallest
for (int k = 0; k < array.length; k++) {
for (int i = 1; i < array[k].length; i++) {
for (int j = i; j > 0; j--) {
if (array[k][j] > array[k][j - 1]) {
int element = array[k][j];
array[k][j] = array[k][j - 1];
array[k][j - 1] = element;
}
}
}
}
System.out.println();
System.out.println("Descending Array element output: ");
arrayOutput(array);
System.out.println();
System.out.println("Average value output by array: ");
float[] arrayAverage = new float[array1stDsize];
float average = 0;
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
average = average + array[i][j];
}
average = (float) (Math.round((average / array[i].length) * 100.0) / 100.0);
System.out.println(i + ". array average value: " + average);
arrayAverage[i] = average;
}
System.out.println();
System.out.println("New array from average values: ");
System.out.println(Arrays.toString(arrayAverage));
System.out.println();
System.out.println("Most valuest array is: ");
double max = 100;
int row = 0;
for (int i = 0; i < arrayAverage.length; i++) {
if (max < arrayAverage[i]) {
max = arrayAverage[i];
row = i;
}
}
System.out.print("Its founded " + row + ". row and it's value is: ");
for (int j = 0; j < array[row].length; j = j + 1) {
System.out.print(" " + array[row][j]);
}
System.out.println();
System.out.println();
//2D array sorting by average values
}
}
public static int[][] arrayOutput(int[][] array) {
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
if (j == 0) {
System.out.print("{ " + array[i][j]);
} else {
System.out.print(", " + array[i][j]);
}
}
System.out.print(" }");
System.out.println();
}
return array;
}
}
The part of your code that calculates the average:
float[] arrayAverage = new float[array1stDsize];
float average = 0;
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
average = average + array[i][j];
}
average = (float) (Math.round((average / array[i].length) * 100.0) / 100.0);
System.out.println(i + ". array average value: " + average);
arrayAverage[i] = average;
}
is slightly wrong, you need to set the average variable to zero before calculating the average of the next rows:
...
arrayAverage[i] = average;
average = 0;
With the Java Streams one can get the matrix sorted by average of rows pretty elegantly, namely:
Arrays.sort(array, comparingDouble(row -> IntStream.of(row)
.average()
.getAsDouble()));
To sort the array one uses the method Arrays.sort, and then for each row one gets its average as a double value IntStream.of(row).average().getAsDouble(), and used as the sorting parameter comparingDouble(....).
A running example:
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
import static java.util.Comparator.comparingDouble;
public class Test {
public static void main(String[] args) {
int array[][] = {{10, 20, 30},{40, 50, 60}, {1,2,3} };
Arrays.sort(array, comparingDouble(row -> IntStream.of(row).average().getAsDouble()));
Arrays.stream(array).map(Arrays::toString).forEach(System.out::println);
}
}
The output:
[1, 2, 3]
[10, 20, 30]
[40, 50, 60]
For the reverse order use instead:
Arrays.sort(array, comparing(row -> IntStream.of(row).average().getAsDouble(), reverseOrder()));
The output:
[40, 50, 60]
[10, 20, 30]
[1, 2, 3]
EDIT: WITH NO STREAMS
Without using streams what you can do is the following:
1 - Get the array with the averages of the matrix rows:
float[] arrayAverage = average(matrix);
You already know how to calculate the average, therefore you just need to extract a method out of the code that you have created, namely:
private static float[]average(int[][] array) {
float[] arrayAverage = new float[array.length];
float sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
sum += array[i][j];
}
arrayAverage[i] = (float) (Math.round((sum / array[i].length) * 100.0) / 100.0);
sum = 0;
}
return arrayAverage;
}
2 - Create an array that will represent the rows and initialized as the following:
int [] row_position = new int [arrayAverage.length];
for(int i = 0; i < row_position.length; i++)
row_position[i] = i;
3 - Sort the arrayAverage using the easiest sort, the bubble sort. While sorting that array update accordingly the positions stored on the row_position:
for(int i=0; i < arrayAverage.length; i++){
for(int j=1; j < (arrayAverage.length-i); j++){
if(arrayAverage[j-1] > arrayAverage[j]){
float temp = arrayAverage[j-1];
arrayAverage[j-1] = arrayAverage[j];
arrayAverage[j] = temp;
int temp_pos = row_position[j-1];
row_position[j-1] = row_position[j];
row_position[j] = temp_pos;
}
}
}
4 - Now that you have the row_positions array that tells you how the sorted rows should be rearranged, you just need to swap the rows accordingly:
int[][] tmp_matrix = new int [matrix.lenght][];
for (int i = 0; i < tmp_matrix.length; i++) {
tmp_matrix[i] = matrix[row_position[i]];
}
matrix = new_matrix;
Bear in mind, however, that for simplicity-sake I have assumed a quadratic matrix of NxN, and the above solution can be improved performance-wise.
At last, made it to work, looks like this.
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class SortArray2D {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Sorting two dimensional arrays!!!");
System.out.print("Enter arrays 1st dimension size 10 - 20: ");
int array1stDsize = sc.nextInt();
System.out.println();
sc.close();
if (array1stDsize > 20 || array1stDsize < 10) {
System.out.println("The number you enteraed is too big or too small!!!");
} else {
int[][] array = new int[array1stDsize][];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = new int[random.nextInt(31) + 10];
for (int j = 0; j < array[i].length; j++) {
int input = new Random().nextInt(900) + 100;
array[i][j] = input;
}
}
System.out.println("Array element output: ");
arrayOutput(array);
// array element sorting from biggest to smallest
for (int k = 0; k < array.length; k++) {
for (int i = 1; i < array[k].length; i++) {
for (int j = i; j > 0; j--) {
if (array[k][j] > array[k][j - 1]) {
int element = array[k][j];
array[k][j] = array[k][j - 1];
array[k][j - 1] = element;
}
}
}
}
System.out.println();
System.out.println("Descending Array element output: ");
arrayOutput(array);
System.out.println();
System.out.println("Average value output by array: ");
float[] arrayAverage = new float[array1stDsize];
for (int i = 0; i < array.length; i = i + 1) {
float sum = 0;
for (int j = 0; j < array[i].length; j = j + 1) {
sum = sum + array[i][j];
}
float average = (float) (Math.round((sum / array[i].length) * 100.0) / 100.0);
System.out.println(i + ". array average value: " + average);
arrayAverage[i] = average;
}
// array lines sorting from by average value increasing
for (int i = 0; i < arrayAverage.length; i = i + 1) {
for (int j = i; j > 0; j--) {
if (arrayAverage[j] < arrayAverage[j - 1]) {
float tmpor = arrayAverage[j];
arrayAverage[j] = arrayAverage[j - 1];
arrayAverage[j - 1] = tmpor;
int[] tmp = array[j];
array[j] = array[j - 1];
array[j - 1] = tmp;
}
}
}
System.out.println();
System.out.print("Array from average values sorted: ");
System.out.println(Arrays.toString(arrayAverage));
System.out.println();
System.out.println("Incerasing Array line output: ");
arrayOutput(array);
System.out.println();
System.out.print("Most valuest array is array: ");
double max = 100;
int row = 0;
for (int i = 0; i < arrayAverage.length; i++) {
if (max < arrayAverage[i]) {
max = arrayAverage[i];
row = i;
}
}
for (int j = 0; j < array[row].length; j = j + 1) {
System.out.print(" " + array[row][j]);
}
}
}
public static int[][] arrayOutput(int[][] array) {
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
if (j == 0) {
System.out.print("{ " + array[i][j]);
} else {
System.out.print(", " + array[i][j]);
}
}
System.out.print(" }");
System.out.println();
}
return array;
}
}
Output sorted 2d array in ascending order:
int[][] arr = {
{12, 54, 87}, // avg 51
{98, 56, 32}, // avg 62
{19, 73, 46}}; // avg 46
Arrays.stream(arr)
// sort an array by the
// average value of the row
.sorted(Comparator.comparingDouble(row ->
// get the average value or 0 if the row is empty {}
Arrays.stream(row).average().orElse(0)))
// string representation
// of the row content
.map(Arrays::toString)
// output line by line
.forEach(System.out::println);
Output:
[19, 73, 46]
[12, 54, 87]
[98, 56, 32]

Fibonacci Sequence using Array in Java

I want to get the fibonacci sequence entered by the user in array. The task given to me was "Ask the user for 2 integer input which will be taken for first and second array elements of size 10 array."
Here is my code.
int limit = 10;
int[] fib = new int[limit];
fib[0] = 0;
fib[1] = 1;
for (int j = 1; j < 2; j++)
{
System.out.print("Enter number " + "[" + j + "]: ");
num[j] = reader.nextInt();
num[j] = fib[j+1] + fib[j+2];
System.out.println("");
}
System.out.print("Result: ");
for(int j = 0; j < limit; j++ )
{
System.out.print(fib[j] + " ");
System.out.print("");
}
I badly need help for this one, been searching for solution for hours and still don't get it.
I'll just make some corrections to your code and explain them:
int limit = 10;
int[] fib = new int[limit];
// fib[0] = 0;
// fib[1] = 1;
// The two lines above are wrong. Even though the real fibonacci sequence starts
// with 0 and 1, the question asks for the first two terms to come from user
// inputs. Instead, you can initialize them below:
// In your old code, you had "j = 1; j < 2; j++". However, that only loops once.
// So, have your condition to be j <= 2 instead: (I'm assuming that you want 1
// and 2 and not zero-based because it should print out "Enter number [1]:" and
// "Enter number [2]:"
for (int j = 0; j < 2; j++) // Not "j < 2"
{
System.out.print("Enter number " + "[" + j + "]: ");
fib[j] = reader.nextInt(); // not num[j] = ..., it's fib[j] = ...
// num[j] = fib[j+1] + fib[j+2];
// You don't need this ^^^
System.out.println("");
}
// Now you need to fill in the array:
for (int j = 2; j < limit; j++)
{
fib[j] = fib[j - 1] + fib[j - 2];
}
System.out.print("Result: ");
for(int j = 0; j < limit; j++)
{
System.out.print(fib[j] + " ");
System.out.print("");
}
You have a number of mistakes here. Try to answer the following things:
What is the purpose of num variable here? You are using it to take input (num[j] = reader.nextInt();), then you are using it to store the Fibonacci sequence as well (num[j] = fib[j+1] + fib[j+2];)!!!
The first loop is only running one time. Assuming that your calculations are correct (which is not in this case!), it will have values for the first fibonacci number only.
Finally when you are printing the Fibonacci numbers, you are not using the num variable! Why?
Anyway, here is a solution to your problem. But, it will not help you unless you understand the logic behind it and you know which line is doing what!!!
int limit = 10;
int[] fib = new int[limit];
for (int j = 0; j < 2; j++)
{
System.out.print("Enter number " + "[" + j + 1 + "]: ");
fib[j] = reader.nextInt(); // These are the first two fibonacci numbers provided by the user
System.out.println("");
}
System.out.print("Result: ");
for(int j = 0; j < limit; j++ )
{
if( j > 1 ) // You only calculate from the third Fibonacci, as the first two were given by user
{
fib[j] = fib[j-1] + fib[j-2];
}
System.out.print(fib[j] + " ");
System.out.print("");
}

Fill the ArrayList by accessing the matrix using a ‘nested’ FOR loop

Using the matrix and ArrayList design from challenge 8, create an array totals to hold the total marks for each of the 5 students. Fill the ArrayList by accessing the matrix using a ‘nested’ FOR loop structure (i will be moving and j will be moving). After filling the totals array, determine the name of the student who had the highest total, and state their name and their average mark (to 1 decimal place).
How can I add the total score of a student from a matrix into a single spot in an ArrayList?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<String> names = new ArrayList<String>();
ArrayList<Integer> total = new ArrayList<Integer>();
int [][] scores = new int [5][6];
int score = 0;
for (int i = 0; i < 5; i++) {
System.out.print("Enter " + "(" + (i+1) + ") friend's name: ");
names.add(input.nextLine());
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
score = 1 + (int)(Math.random() * ((20 + 1)));
scores[i][j] = score;
}
total.add(i,0);
}
}
Just keep sum of scores from row, and insert it to total array
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<String> names = new ArrayList<String>();
ArrayList<Integer> total = new ArrayList<Integer>();
int [][] scores = new int [5][6];
int score = 0;
for (int i = 0; i < 5; i++) {
System.out.print("Enter " + "(" + (i+1) + ") friend's name: ");
names.add(input.nextLine());
}
for (int i = 0; i < 5; i++) {
int tlsc = 0;
for (int j = 0; j < 6; j++) {
score = 1 + (int)(Math.random() * ((20 + 1)));
tlsc+=score;
scores[i][j] = score;
}
total.add(tlsc);
}
}

Categories

Resources