Using Multi-Dimensional Arrays for Matrix Multiplication Java [duplicate] - java

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
I'm trying to write a code that multiplies two given matrices together and displays the results. Here is the code I have down so far:
public static void main(String[] args) {
double firstMatrix[][] = {{1, 2}, {3, 4}, {5, 6}};
double secondMatrix[][] = {{1, 2, 3}, {4, 5, 6}};
double[][] thirdMatrix = multiplyMatrix((firstMatrix), (secondMatrix));
System.out.println("The product of the matrices is ");
for (int i = 0; i < thirdMatrix.length; i++) {
for (int j = 0; j < thirdMatrix[0].length; j++) {
System.out.print(firstMatrix[i][j] + " ");
if (i == 1 && j == 2) {
System.out.print(" * ");
} else {
System.out.print(" ");
}
}
for (int j = 0; j < thirdMatrix[0].length; j++) {
System.out.print(secondMatrix[i][j] + " ");
if (i == 1 && j == 2) {
System.out.print(" = ");
} else {
System.out.print(" ");
}
}
for (int j = 0; j < thirdMatrix[0].length; j++) {
System.out.printf("%.1f", thirdMatrix[i][j]);
}
System.out.println();
}
}
public static double[][] multiplyMatrix(double[][] a, double[][] b) {
double c[][] = new double[3][3];
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < b.length; j++) {
for (int k = 0; k < a.length; k++) {
c[i][j] += ((a[i][k]) * (b[k][j]));
}
}
}
return c;
}
But when I try to execute the program I receive an Array Index out of Bounds Error which shouldn't be the case since my for loops are making sure not to step out of bounds from the array. I don't understand where to change my code because it looks fine until I try to execute. Any help is really appreciated.

If 1st matrix's dimensions is mxn and the 2nd's nxp then the product's dimensions mxp. Right?
So this 2nd level of the triple loop should iterate through the 2nd dimension of the product array:
for (int j = 0; j < b.length; j++)
should be:
for (int j = 0; j < b[0].length; j++)
b[0].length is the number of columns of the matrix b.
Also the 3d level of the triple loop should be:
for (int k = 0; k < b.length; k++)
b.length is the number of rows of the matrix b which is equal to the number of columns of the matrix a.
Edit
In a generalized version you could change this:
double c[][] = new double[3][3];
to
double c[][] = new double[a.length][b[0].length];

public static void main(String[] args) {
double firstMatrix[][] = {{1, 2}, {3, 4}, {5, 6}};
double secondMatrix[][] = {{1, 2, 3}, {4, 5, 6}};
double[][] thirdMatrix = multiplyMatrix((firstMatrix), (secondMatrix));
System.out.println("The product of the matrices is ");
for (int i = 0; i < thirdMatrix.length; i++) {
for (int j = 0; j < firstMatrix[0].length; j++) {// check this one
System.out.print(firstMatrix[i][j] + " ");
if (i == 1 && j == 2) {
System.out.print(" * ");
} else {
System.out.print(" ");
}
}
for (int j = 0; j < thirdMatrix.length; j++) {
if (i <= 1) {// you need are condition to stop
System.out.print(secondMatrix[i][j] + " ");
if (i == 1 && j == 2) {
System.out.print(" = ");
} else {
System.out.print(" ");
}
}
}
for (int j = 0; j < thirdMatrix[0].length; j++) {
System.out.print(thirdMatrix[i][j]);
}
System.out.println();
}
}
public static double[][] multiplyMatrix(double[][] a, double[][] b) {
double c[][] = new double[3][3];
for (int i = 0; i < c.length; i++) {
// Change b.length to b[0].length;
for (int j = 0; j < b[0].length; j++) {
// Change a.length to a[0].length;
for (int k = 0; k < a[0].length; k++) {
c[i][j] += ((a[i][k]) * (b[k][j]));
}
}
}
return c;
}

Related

Max increase to keep city skyline

I'm trying to solve "Max Increase to Keep City Skyline" LeetCode problem.
Testing the algorithm locally, I manage to find the "skyline" for the "horizontal" view correctly ("horizontal" = the view you'd see by looking at the matrix's columns).
Though, for the "vertical" view ("vertical" = the view you'd see by looking at the matrix's rows), my last 2 values in the verticalView array aren't the correct ones, and I don't understand why.
I added the println to display the variable's values.
I don't understand why when verticalView[2] = 8 (this happens when i = 0, j = 2), i = 2 and j = 2, verticalView[2] has become 0.
import java.util.Arrays;
class Solution {
public static int maxIncreaseKeepingSkyline(int[][] grid) {
int[] verticalView = new int[grid.length];
int[] horizontalView = new int[grid[0].length];
for (int i = 0; i < grid.length; i++) {
verticalView[i] = 0;
horizontalView[i] = 0;
for (int j = 0; j < grid[0].length; j++) {
boolean b = grid[i][j] > verticalView[j];
System.out.println("verticalView[" + j + "] = " + verticalView[j]);
if (grid[i][j] > verticalView[j] /* b */) verticalView[j] = grid[i][j];
if (grid[i][j] > horizontalView[i]) horizontalView[i] = grid[i][j];
System.out.println("grid[" + i + "][" + j + "] > verticalView[" + j + "] = " + b);
System.out.println("grid[" + i + "][" + j + "] = " + grid[i][j]);
System.out.println("verticalView[" + j + "] = " + verticalView[j]);
System.out.println();
}
}
System.out.println("Vertical view: " + Arrays.toString(verticalView));
System.out.println("Horizontal view: " + Arrays.toString(horizontalView));
// int[] verticalView = {9,4,8,7};
// int[] horizontalView = {8,7,9,3};
int sum = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
while (grid[i][j] < verticalView[j] & grid[i][j] < horizontalView[i]) {
grid[i][j]++;
sum++;
}
}
}
// for (int i = 0; i < grid.length; i++) {
// for (int j = 0; j < grid[0].length; j++) {
// System.out.print(grid[i][j] + " ");
// }
// System.out.println();
// }
return sum;
}
public static void main(String[] args) {
int[][] n = {{3, 0, 8, 4}, {2, 4, 5, 7}, {9, 2, 6, 3},{0, 3, 1, 0}};
System.out.println("Solution: " + maxIncreaseKeepingSkyline(n));
}
}
The mistake in your code is in:
verticalView[i] = 0;
horizontalView[i] = 0;
The default values of the array are zero in java.
You are changing values to zero even if they are updated to something other than zero.
Simplified Solution to the Problem:
import java.util.Arrays;
class Solution {
public static int maxIncreaseKeepingSkyline(int[][] grid) {
int[] verticalView = new int[grid.length];
int[] horizontalView = new int[grid[0].length];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] > verticalView[j]) verticalView[j] = grid[i][j];
if (grid[i][j] > horizontalView[i]) horizontalView[i] = grid[i][j];
}
}
int sum = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
while (grid[i][j] < verticalView[j] & grid[i][j] < horizontalView[i]) {
grid[i][j]++;
sum++;
}
}
}
return sum;
}
public static void main(String[] args) {
int[][] n = {{3, 0, 8, 4}, {2, 4, 5, 7}, {9, 2, 6, 3},{0, 3, 1, 0}};
System.out.println("Solution: " + maxIncreaseKeepingSkyline(n));
}
}
Looks good!
We can also use Math.max() for just simplifying it a bit, nothing major though:
public class Solution {
public static final int maxIncreaseKeepingSkyline(
final int[][] grid
) {
int[] rows = new int[grid.length];
int[] cols = new int[grid.length];
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid.length; col++) {
rows[row] = Math.max(rows[row], grid[row][col]);
cols[col] = Math.max(cols[col], grid[row][col]);
}
}
int maxIncrease = 0;
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid.length; col++) {
maxIncrease += Math.min(rows[row], cols[col]) - grid[row][col];
}
}
return maxIncrease;
}
}

Multiply 2 matrices 4x1 and 1x4

The program should multiply 2 matrices 4x1 and 1x4 and output the result to the console (matrix 4X4). But nothing displays. What's the problem?
public class Matrix {
public static void main(String[] args) {
int[][] matrixA = new int[4][1];
int[][] matrixB = new int[1][4];
int[][] matrixC = new int[4][4];
matrixA[0][0] = 1;
matrixA[1][0] = 2;
matrixA[2][0] = 3;
matrixA[3][0] = 4;
matrixB[0][0] = 4;
matrixB[0][1] = 3;
matrixB[0][2] = 2;
matrixB[0][3] = 1;
for (int i = 0; i < 4; i++) { // A rows
for (int j = 0; j < 4; j++) { // B columns
for (int k = 0; k < 1; k++) { // A columns
matrixC[i][j] += matrixA[i][k] * matrixB[k][j];
System.out.print(matrixC[i][j] + " ");
}
}
}
int j = 0;
for (int i = 0; i < 4; i++) {
for (int k = 0; k < 1; k++)
System.out.print(matrixC[i][j] + " ");
System.out.println();
}
} //end main
} //end class
You introduced a variable j before your second set of for loops. Also, even if they're optional, I would highly recommend always including braces. And k < 4. Like,
for (int i = 0; i < 4; i++) {
for (int k = 0; k < 4; k++) {
System.out.print(matrixC[i][k] + " "); // not [i][j]
}
System.out.println();
}
or just use Arrays.deepToString(Object[]) like
System.out.println(Arrays.deepToString(matrixC));
Hope this helps:
public class Matrix {
public static void main(String[] args) {
int[][] matrixA = {{1}, {2}, {3}, {4}};
int[][] matrixB = {{4, 3, 2, 1}};
int[][] matrixC = new int[4][4];
for (int i = 0; i < 4; i++) { // A rows
for (int j = 0; j < 4; j++) { // B columns
for (int k = 0; k < 1; k++) { // A columns
matrixC[i][j] += matrixA[i][k] * matrixB[k][j];
System.out.print(matrixC[i][j] + " ");
}
}
System.out.println();
}
}
}
Output:
4 3 2 1
8 6 4 2
12 9 6 3
16 12 8 4

Trouble multiplying 2D arrays of different dimensions in Java

I've got the following code, I'm trying to get it to multiply array a by array b and produce array c. I've browsed several questions on here and for some reason I can't get the array to produce the correct results, I believe because it's not multiplying the right indices by one another. Any help would be greatly appreciated, as I am still trying to grasp how array multiplication works. Here is the code:
class Main
{
public static void main (String[] args)
{
int[][]a =
{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
//print array a
};
for(int i = 0; i < a[0].length-1; i++)
{
for(int j = 0; j < a[0].length; j++)
{
System.out.print(a[i][j] + " ");
}
System.out.println();
}
int[][]b =
{
{-1,-2,-3},
{-4,-5,-6},
{-7,-8,-9},
{-10,-11,-12},
};
System.out.println();
//print array b
for(int i = 0; i < b.length; i++)
{
for(int j = 0; j < b.length-1; j++)
{
System.out.print(b[i][j] + " ");
}
System.out.println();
}
System.out.println();
int[][]c = new int[a.length][b[0].length];
if(b.length == a[0].length)
{
for(int i = 0; i < a.length; i++)
{
for (int j = 0; j < b[0].length; j++)
{
for (int k = 0; k < a[0].length; k++)
{
c[i][j] = a[i][k]*b[k][j];
}
}
}
}
else
{
System.out.println("Dimension requirements not satisfied for accurate calculation");
}
for(int i = 0; i < c.length; i++)
{
for(int j = 0; j < c.length; j++)
{
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
}
Change c[i][j] = a[i][k]*b[k][j]; to c[i][j] += a[i][k]*b[k][j];
The answer by #Jeffrey Chen is correct because in the matrix multiplication each row of the first matrix multiply by each column of second matrix
In your case row 1 of matrix a is 1, 2, 3, 4
Column 1 of matrix b is -1, -4, -7, -10
So the answer is (1*-1)+(2*-4)+(3*-7)+(4*-10)
= -1-8-21-40 = -70
Then the first row of matrix a multiply by second column of matrix b
(1*-2)+(2*-5)+(3*-8)+(4*-11)
= -2-10-24-44 = -80
And so on
So the following is correct
c[i][j] += a[i][k] * b[k][j];

how to sort multidimensional Array in java logically?

i need to sort a multidimensional Array without going for any predefined method, it will be logically..
int arr[][]={{5,2,3},{2,8,5},{7,4,5}};
in the case of single dimensional Array,
int num[]={125,28,31,40,12};
for(int i=0;i<=num.length-1;i++){
for(int k=0;k<=num.length-2;k++){
if(num[k]>num[k+1]){
int temp=0;
temp=num[k];
num[k]=num[k+1];
num[k+1]=temp;
}
}
}
for(int s=0;s<=num.length-1;s++){
System.out.println(num[s]);
}
what would be in case of multidimensional array?
public static void main(String[] args) {
int u, arr[][] = {{1, 7, 2}, {9, 12}, {54, 25, 10}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
for (int k = j + 1; k < arr[i].length; k++) {
if (arr[i][j] > arr[i][k]) {
u = arr[i][k];
arr[i][k] = arr[i][j];
arr[i][j] = u;
}
}
System.out.print(arr[i][j] + ",");
}
System.out.println(" ");
}
}

Convert 1D to 2D java.lang.ArrayIndexOutOfBoundsException

I try to convert 1D to 2D array, but I keep getting java.lang.ArrayIndexOutOfBoundsException, and I have tried whatever I could find on the stackoverflow or internet, but I do not understand why I have this issue?
public class Arrayto2DArray {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] a = {0,1, 6, 83, 4, 5, 12, 7};
int[][] b = new int[4][4];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[i].length; j++) {
b[i][j]=0;
System.out.print(b[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < b[i].length; j++) {
try{
b[i][j] = a[i+j*4];
}catch(Exception e){
e.printStackTrace();
System.out.println(e);
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(b[i][j]);
}
System.out.println();
}
}
}
I kind of know why I get this error and it because of this line
b[i][j] = a[i+j*4];
but I cannot come up any formula better than this.
Consider the second for-loop
Lets say when i = 3 and j= 3
a[i+j*4] evaluates to a[15] which is out of the array
When you declare you 2-d array, you specified int[][] b = new int[4][];, meaning that the first inner for loop for (int j = 0; j < b[i].length; j++) should result in a NullPointerException since b[i].length has no predefined length. Before intering the inner for loop, you should define the size of each b[i] like b[i] = new int[somenumber]
In regards to convert the 1d loop to a 2d, you need to define the rule around spliting it into the 2-d array. Then accordingly the second for loop need modification
EDIT:You modified your code to have an int[4][4] array, which means you have 16 placeholders. Your 1-d array contain only 8 placeholders. It depends on how you want to sort the array, like it can be
b 0 1 2 3
0 0 1 6 83
1 4 5 12 7
2 0 0 0 0
3 0 0 0 0
or any other pattern
Assuming the length of 1-d array is 8 and the total index of 2-d array is 16, the following is more of a general solution:
public static void main(String[] args) {
// TODO code application logic here
int[] a = { 0, 1, 6, 83, 4, 5, 12, 7 };
int[][] b = new int[4][4];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[i].length; j++) {
b[i][j] = 0;
System.out.print(b[i][j] + "\t");
}
System.out.println();
}
System.out.println("--------------------------");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < b[i].length; j++) {
try {
if ((j + i * 4) < a.length)
b[i][j] = a[j + i * 4];
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(b[i][j] + "\t");
}
System.out.println();
}
}
What is wrong is your 2D array is a 4*4, so that means for each index, there will be 4 elements i.e. say values. So there would be a total of 16 values, so you would need a 1D array with 16 elements for the above code to work. Right now you have only 8 values in your 1D array.
I think your code should change like this
public class Arrayto2DArray {
public static void main(String[] args) {
// TODO code application logic here
int[] a = {0,1, 6, 83, 4, 5, 12, 7};
int[][] b = new int[4][2];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[i].length; j++) {
b[i][j]=0;
System.out.print(b[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < b[i].length; j++) {
try{
b[i][j] = a[i+j*4];
}catch(Exception e){
e.printStackTrace();
System.out.println(e);
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; j++) {
System.out.print(b[i][j]+" ");
}
System.out.println();
}
}
}
Your correct formula should be like.
int[] a = {0,1, 6, 83, 4, 5, 12, 7};
int[][] b = new int[4][2];
int k=0;
for (int i = 0; i < b.length; i++) { // Column of 2D array
for (int j = 0; j < b[0].length; j++) { // Row of 2D array
b[i][j]= a[k++];
System.out.println(b[i][j]);
}
}
Edit:
For general case, If your row is fixed at 4 but column is not fixed than your 2D conversion formula should be like below.
int col = a.length / 4;
int remainder = a.length % 4;
if (remainder > 0) {
col = col + 1; // Get the correct column size.
}
int[][] b = new int[4][col];
int k = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < col; j++) {
if (k < a.length) {
b[i][j] = a[k];
System.out.println(b[i][j]);
}
k++;
}
}

Categories