I am trying to get the sum of my array called matrix. However when I compile it I receive this error: bad operand types for binary operator '+' first type: int; second type:int[]. I do not understand why this is causing an error. Please help me understand, here is my code:
/**
Sophia Ali
1. Matrix, getSumMatrix, getSumMatrixDiag:
Email just Matrix.java.
Write a class called Matrix that contains a private 2-dimensional int
array called 'matrix' that can be up to 10 rows by 10 columns maximum.
Use two constants MAXROWS=10 and MAXCOLS=10 to construct 'matrix.'
The Matrix class will also need the following attributes:
private int rows; // number of rows to use in matrix
private int cols; // number of cols to use in matrix
The rows and cols will contains values that are less than equal to
MAXROWS and MAXCOLS.
Write a default Matrix class constructor that constructs the 'matrix'
array with the following values:
{{1,2,4,5},{6,7,8,9},{10,11,12,13}, {14,15,16,17}}
The constructor must also set the rows and cols variables to match the
above matrix.
Write a method 'getSumMatrix' that returns the sum of all the integers
in the array 'matrix'.
Write a method 'getSumMatrixDiag' that returns the sum of all the
integers in the major diagonal of the array 'matrix'. A major diagonal is
the diagonal formed from the top left corner to the bottom right corner of
the matrix.
You do not have to write a TestMatrix class to test the Matrix class.
Just use the BlueJ object creation and testing feature.
*/
public class Matrix
{
static final int MAXROWS = 10;
static final int MAXCOLS = 10;
private int rows;
private int cols;
private int [][] matrix = new int [MAXROWS][MAXCOLS];
public Matrix()
{
int matrix[][] =
{
{1, 2, 4, 5},
{6, 7, 8, 9},
{10, 11, 12, 13},
{14, 15, 16, 17}};
getSumMethod(matrix);
getSumMatrixDiag(matrix);
}
public int getSumMethod(int[][] matrix)
{
int sum = 0;
for (int i = 0; i < matrix.length; i++) {
sum += matrix[i];
}
return sum;
}
/*
int i, result;
result = 0;
for(i=0; i < matrix.length; i++)
{
i++;
result = result + i;
}
return result;
}
*/
public int getSumMatrixDiag(int[][] matrix)
{
int sum = 0;
for (int i =0; i< matrix.length; i++)
{
i++;
sum = (int)(sum + matrix[i][i]);
}
return sum;
}
}
When summing a multidimensional matrix, you must loop over all dimensions. So in your case you have a two dimensional array, therefore you need two nested loops to traverse both arrays.
Your loop:
int sum = 0;
for (int i = 0; i < matrix.length; i++) {
sum += matrix[i];
}
return sum;
Should look like:
int sum = 0;
for(int i =0; i < matrix.length){
for(int j = 0; j < matrix[i].length; j++){
sum += matrix[i][j];
}
}
return sum;
Related
I think I'm missing something small but I can't tell what it might be. I'm trying to create a method that will transpose a matrix. For example, if I input a 2x3 matrix, it'll output a 3x2 matrix.
If I input {1, 1, 1}
{1, 1, 1}
I get an IndexOutOfBoundsException
It's telling me that my error occurs on the line that "says newTranspose.data[j][i] = data[i][j];" but I don't know what else to do. I've tried swapping i's and j's and numRows/numColumns for data.length but I'm stuck at this point.
Above this method, I have instance variables 'private in numRows' and 'private int numColumns' to set the dimensions of the matrix. I have another instance variable 'private int data[][]' that's the internal storage of the matrix elements. Then I have a Constructor for a new Matrix that automatically determines dimensions.
public Matrix(int d[][]) {
// d.length is the number of 1D arrays in the 2D array
numRows = d.length;
if (numRows == 0)
numColumns = 0;
else
numColumns = d[0].length; // d[0] is the first 1D array
// create a new matrix to hold the data
data = new int[numRows][numColumns];
// copy the data over
for (int i = 0; i < numRows; i++)
for (int j = 0; j < numColumns; j++)
data[i][j] = d[i][j];
}
public Matrix transpose() {
Matrix newTranspose = new Matrix(data);
for (int i = 0; i < numRows; i++)
for (int j = 0; j < numColumns; j++)
newTranspose.data[j][i] = data[i][j];
return newTranspose;
}
The problem is with this statement: Matrix newTranspose = new Matrix(data)
One effect of that statement will be that newTranspose will have the same contents, but more importantly, the same number of rows and same number of columns as the original matrix. The nested loops are sure to throw an ArrayIndexOutOfBoundsException whenever the source array is not square.
One way to fix it is to declare a new 2D array:
public Matrix transpose () {
int [][] hold = new int [numColumns] [numRows];
for (int i = 0; i < numRows; i++)
for (int j = 0; j < numColumns; j++)
hold [j][i] = data[i][j];
return new Matrix (hold);
}
I made this code in order to swap places with the first column and the last column in a 3x3 Matrix. I would need to use 2 different methods, one to print the original matrix and one to print the modified matrix.
I was able to do the first one, but I have problems with the second.
public class SwapMatrix {
public static void main(String[] args) {
int matrix [][] =
{{3, 4, 5},
{7, 8, 9},
{1, 2, 3}};
System.out.println("\n Normal Matrix:");
print(matrix);
//int matrixModified [][] = swap(matrix);
//System.out.println("\n New Matrix:");
//print(matrixModified);
}
public static void print (int matrix[][]){
for (int i=0; i<matriz.length; i++){
for (int j=0; j<matrix[0].length; j++){
System.out.print(matriz [i][j]+ "\t");
}
System.out.println();
}
}
}
If you want to print the matrix backwards, all you have to do is to count reverse in your loop.
public static void printReverse (int matrix[][]){
for (int i=0; i<matrix.length; i++){ // lines
for (int j=matrix[0].length-1; j>=0; j--){ // columns backwards
System.out.print(matrix [i][j]+ "\t");
}
System.out.println();
}
}
You can implement the swap() method in two ways: either by creating a new matrix or by swapping the columns of the given matrix in place.
1. Firstly, you need to create a new matrix.
And then iterate over it with a nested for loop assigning the elements of each row in the new matrix in reversed order. I.e. the value of the first element of the row at position 0 would be assigned to the element at position matrix[0].length - 1 and vice versa (the same hold true for all other elements).
public static int[][] swap(int[][] matrix) {
int[][] result = new int[matrix.length][matrix[0].length];
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
result[row][(matrix[0].length - 1) - col] = matrix[row][col];
}
}
return result;
}
2. To swap the given matrix in place, you need to create a nested for loop. Iteration in the inner loop should happen only until the middle of the array representing each row (that's important, if'll iterate over the full length of a row elements will get swapped twice and the matrix will remain the same).
public static int[][] swapInPlace(int[][] matrix) {
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length / 2; col++) {
int temp = matrix[row][(matrix[0].length - 1) - col];
matrix[row][(matrix[0].length - 1) - col] = matrix[row][col];
matrix[row][col] = temp;
}
}
return matrix;
}
Sidenote: although int matrix[][] is a valid syntax inherited from the C language, it's not a good practice to use it because this notation mixes two completely different notions: a variable name and a type. The preferred way to define an array int[][] matrix.
My goal for this program is to create a 2D-array ratings whose size is specified by the first two arguments from the command line. args[0] would represent the number of rows r and arg[1] would represent the number of columns c. The next arguments that follow would all be used to fill in the array. So if the command-line argument was 3 2 5 2 3 3 4 1. I would hope that the array would be 3 rows by 2 columns. The value 5 would be in ratings[0][0], the value 2 would be in ratings[0][1], the value 3 would be in ratings[1][0], etc. After that, I want to compute the sum of each column. So column 0 would be 12 and column 1 would be 6 in this scenario.
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int c = Integer.parseInt(args[1]);
int[][] ratings = new int[r][c];
int z = 2;
int y = 3;
int x = 0;
int counting = 0;
int sum = 0;
for (int rows = 0; rows < ratings.length; rows++ ) {
for (int column = 0; column < ratings[c].length; column++){
ratings[rows][column] = Integer.parseInt(args[z]);
sum += ratings[rows][column];
z++;
}
System.out.println(sum);
sum = 0;
}
//System.out.println(movieRating);
}
This is my attempt at summing the columns but this right now just sums 5 and 2, 3 and 3, 4 and 1. I want the columns not the rows to be summed but do not know how to fix it. Thank you
You seem to be adding the values to the 2D array correctly. What you're missing is an additional nested loop to print out the column totals:
for (int i = 0; i < ratings[c].length; i++) {
int colSum = 0;
for (int j = 0; j < ratings.length; j++) {
colSum += ratings[j][i];
}
System.out.println(colSum);
}
Add that where you currently have that //System.out.println(movieRating); line. Since you were adding the numbers to the array row-wise, you need to flip the for loops to be able to sum the columns.
Things you did right
You correctly initialized the ratings 2D-array with the values given on the command line. Let me re-write this below without your attempt at computing the columns' sum. Note that I renamed the variables so that the indices used in the for loop are single letter variable.
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
argIndex++;
}
}
}
Thing you didn't get right
The ratings array is filled row by row. In the code you posted, you compute in variable sum the sum of the elements inserted in the same row. This is the reason why it doesn't print the results you expected.
To compute the sum of each columns, I would recommend you create a new array in which to store this result. Integrating it with the code above:
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int[] columnSums = new int[columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
columnSums[c] += ratings[r][c];
argIndex++;
}
}
// array columnSums contains your results
}
I have changed your original code with a simpler version.
Let me know if you have problems understanding the solution.
public static void main(String[] args)
{
int row = Integer.parseInt(args[0]);
int col = Integer.parseInt(args[1]);
int arrayLength = row * col; // use a single dimension array, for simplicity
int[] ratings = new int[arrayLength]; // the array size is based on the rows and columns
// add data to the 'ratings' array
// This is not actually needed because the conversion can be done directly when the columns are summed up
for(int i = 0; i < arrayLength; i++)
{
ratings[i] = Integer.parseInt(args[i + 2]);
}
// sum up the columns using the % operator
int[] result = new int[col];
for(int i = 0; i < arrayLength; i++)
{
result[i % col] += ratings[i];
}
// print result
for(int i = 0; i < result.length; i++)
{
System.out.println(String.format("Movie %d rating is %d", i, result[i]));
}
}
PS: you are missing the validation around the String to int conversion and checks around the correctness of the user input
I am trying to display the current row that has the max value. So far I have the max value by adding the elements in the array but I am trying to display the specific row it is in. For example:
{4,4,4}
{5,5,5}
:25 is the biggest val possible going by row to row
The max value here would be 15 as my code looks and finds the maximum addition in each row in a 2D array. How would I get my code to display the row {5,5,5} as well as the actual maximum addition that is possible with the given rows.
Here is my current code:
public class review{
int largestRowsSum(int[][] arr){
int sum = 0;
int largest = 0;
for (int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
sum += arr[i][j];
}
if(sum > largest){
largest = sum;
}
sum = 0;
}
return largest;
}
}
First, your current method could be simplified and static. Like,
static int largestRowsSum(int[][] arr) {
int sum = Arrays.stream(arr[0]).sum();
for (int i = 1; i < arr.length; i++) {
sum = Math.max(Arrays.stream(arr[i]).sum(), sum);
}
return sum;
}
Second, you could invoke that method and then iterate the array to find the index of the array with the matching sum. Like,
static int largestRowIndex(int[][] arr) {
int target = largestRowsSum(arr);
for (int i = 0; i < arr.length; i++) {
if (Arrays.stream(arr[i]).sum() == target) {
return i;
}
}
return -1;
}
Finally, call that method and use the returned index to display the row and correct sum. Like,
public static void main(String[] args) {
int[][] arr = { { 4, 4, 4 }, { 5, 5, 5 } };
int n = largestRowIndex(arr);
System.out.printf("The largest row is %s and the sum is %d.%n",
Arrays.toString(arr[n]), Arrays.stream(arr[n]).sum());
}
Outputs, the row {5,5,5} as well as the actual maximum, as requested
The largest row is [5, 5, 5] and the sum is 15.
I hope this will print one largest value. but it need 10 largest elements in an 3D array.
public class foo{
Public static void main(String[] args){
int row,col,dep=3;
int[][][] value=new int[row][col][dep];
/* insert the value from user or initialize the matrix*/
int max=0;
for(row=0;row<3;row++)
for(col=0;col<3;col++)
for(dep=0;dep<3;dep++)
if(value[row][col][dep]>max)
max=value[row][col][dep];
System.out.println(max);
}
}
You can add all integers into a List<Integer>, sort it, and then get the X max numbers of it:
public class foo {
public static void main(String[] args) {
int row = 3, col = 3, dep = 3;
int[][][] value = new int[row][col][dep];
value[1][2][1] = 10;
value[1][0][1] = 15;
List<Integer> listWithAll = new ArrayList<>();
/* insert the value from user or initialize the matrix*/
int max = 0;
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
for (dep = 0; dep < 3; dep++)
listWithAll.add(value[row][col][dep]);
listWithAll.sort(Collections.reverseOrder());
for (int i = 0; i < 10; i++) {
System.out.println(listWithAll.get(i));
}
}
}
which prints:
15 10 0 0 0 0 0 0 0 0
or using Java 8 streams only:
List<Integer> max10 = listWithAll.stream()
.sorted(Collections.reverseOrder())
.limit(10)
.collect(Collectors.toList());
max10.forEach(System.out::println);
Here is a way to do it with streams. I used a complete 2 x 2 x 2 array to make it easier but it would work with any int[][][] array. Instead of using nested loops, I just flatMapped the arrays.
Initialize the array.
int[][][] v = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
Now get the top4 values (or top N values) and put them in a list.
int top4 = 4;
List<Integer> top4Max =
Arrays.stream(v).flatMap(Arrays::stream).flatMapToInt(
Arrays::stream).boxed().sorted(
Comparator.reverseOrder()).limit(top4).collect(
Collectors.toList());
System.out.println(top4Max);
Prints
8 7 6 5
The Arrays.stream strips one level of array. The flatMap takes those and further flattens them into a single dimenion array. The flatMapToInt flattens that into a stream of ints where they are sorted and processed into a limited collection.
If required, you could also put them in an array instead of a list.
Alternatively, one could create a small array and use it as with a normal findmax function.
public class Array_3D {
public static void main(String[] args) {
int row = 3, col = 3, dep = 3;
int[][][] value = new int[row][col][dep];
value[1][2][1] = 10;
value[1][0][1] = 15;
int[] topten = new int[10]; //array to hold max values
int count = 0;
int candidate = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
for (int k = 0; k < dep; k++) {
if (count < 10) { //start with first ten values
topten[count] = value[i][j][k];
count++;
}
else {
candidate = value[i][j][k];
for (int x = 0; x < 10; x++) { //loop for loading top values
if (candidate > topten[x]) {
topten[x] = candidate;
break; //exit on first hit
}
}
}
}
}
}
for (int i = 0; i < 10; i++) {
System.out.print(topten[i] + " ");
}
System.out.println();
}
}
I don't know which method is faster for large 3D arrays; here we have to run a small loop at every point in the 3D array, vs creating an entirely new list and sorting it. Clearly this wins in memory usage, but not sure about speed. [Edit note this returns an unsorted array of the top ten values as is].