I am trying to instantiate and return my results as an object, but I am not sure how to do so. Any help would be appreciated! Thanks.
Current Code
private static Results stats(int[] data) {
int sum = 0,
range,
count = 0,
max = data[0],
min = data[0],
mode,
middle = data.length / 2,
cardinality = data.length;
double mean = 0,
median;
Stats Results = new Stats();
for (int i = 0; i < data.length; i++) {
sum += data[i];
if (data[i] < min){
min = data[i];
}
if (data[i] > max){
max = data[i];
}
if (data[i] > count){
count = data[i];
mode = i;
}
}
if (data.length % 2 == 1){
median = data.length / 2;
} else {
median = data[middle - 1] + data[middle] / 2;
}
mean = sum / data.length;
range = max - min;
}
Edit Here is the class which is inside public class Stats
static class Results {
public int[] data;
public int cardinality;
public int range;
public double mean;
public double median;
public int mode;
public boolean nomode;
}
Here is all of the code (Formatting is a little messed up when I pasted it in)
public class Stats {
public static void main(String[] argv) {
int[][] data = {
{ 0, 2, 4, 5, 5, 8 },
{ 1, 5, 6, 6, 6, 7, 9 },
{ -4, -2, -2, 3, 12, 12, 42 },
{ 0 },
{ 1, 2 },
{ 1, 1 },
{ 1, 2, 3 },
{ 5, 5, 5, 5, 5 },
{ -2, -2, 0, 1, 1, 2, 2, 2 },
{ -7, 0, 0, 3, 3, 3, 4, 4 },
};
for (int i = 0; i < data.length; i++) {
Results results = stats(data[i]);
printResults(results);
}
}
private static void printArray(int[] x, boolean nl) {
System.out.print("[");
for (int i = 0, j = x.length - 1; i < j; i++)
System.out.print(x[i] + ",");
System.out.print(x[x.length - 1] + "]");
if (nl) System.out.println();
}
private static void printResults(Results r) {
printArray(r.data, true);
StringBuffer sb = new StringBuffer("...mean: ");
sb.append(r.mean).append("; median: "). append(r.median).
append("; mode: "). append(r.nomode ? "modeless" : r.mode).
append("; cardinality: ").append(r.cardinality).
append("; range: ").append(r.range);
System.out.println(sb);
System.out.println();
}
static class Results {
public int[] data;
public int cardinality;
public int range;
public double mean;
public double median;
public int mode;
public boolean nomode;
}
private static Results stats(int[] data) {
int sum = 0,
range,
count = 0,
max = data[0],
min = data[0],
mode,
middle = data.length / 2,
cardinality = data.length;
double mean = 0,
median;
Stats Results = new Stats();
for (int i = 0; i < data.length; i++) {
sum += data[i];
if (data[i] < min){
min = data[i];
}
if (data[i] > max){
max = data[i];
}
if (data[i] > count){
count = data[i];
mode = i;
}
}
if (data.length % 2 == 1){
median = data.length / 2;
} else {
median = data[middle - 1] + data[middle] / 2;
}
mean = sum / data.length;
range = max - min;
}
}
Method declaration should be like below:
private static Results stats(int[] data){
....
.....
return Results;
}
Return type should be class name not object name which is Stats
and add return statement as above before method ends.
Related
I am implementing longest increasing path problem of leetcode.
Given an integer matrix, find the length of the longest increasing path.
From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).
Example 1:
Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
So Below is my implementation tries a lot on recursion, but not able to understand why it is not giving correct result why maxDist decreases from 4 to 3 to 2 in this example, as this variable is is global not local.
public class LongestIncreasingPath {
private static final int[][] dirs = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
private int m, n;
int maxDist;
public int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0)
return 0;
m = matrix.length;
n = matrix[0].length;
int ans = 1;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j) {
dfs(matrix, i, j, 1);
ans = Math.max(ans, maxDist);
}
return ans;
}
private int dfs(int[][] matrix, int i, int j, int dist) {
for (int[] d : dirs) {
int x = i + d[0], y = j + d[1];
if (0 <= x && x < m && 0 <= y && y < n && matrix[x][y] > matrix[i][j]) {
maxDist = Math.max(maxDist, dfs(matrix, x, y, dist+1));
}
}
return dist;
}
public static void main(String[] args) {
int[][] nums = { { 9, 9, 4 }, { 6, 6, 8 }, { 2, 1, 1 } };
LongestIncreasingPath lIP = new LongestIncreasingPath();
System.out.println(lIP.longestIncreasingPath(nums));
}
}
The following is a working version, tested on 2 test cases (only). Please note the comments about bugs and some changes in structure:
public class LongestIncreasingPath {
private static final int[][] dirs = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
private int rows, cols;
//avoid non-volatile class variable that may be updated by more than one thread
//use local variables instead
//private int maxDist;
public int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0) return 0;
rows = matrix.length;
cols = matrix[0].length;
int maxDist = 0; //retain max found
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
//bug fix: use distance (matrix[row][col]) instead of 1
int distance = dfs(matrix, row, col, matrix[row][col]);
maxDist = Math.max(distance, maxDist);
}
}
return maxDist;
}
private int dfs(int[][] matrix, int row, int newCol, int dist) {
int maxDist = dist;
for (int[]dir : dirs) {
int newRow = row + dir[0], y = newCol + dir[1];
if (0 <= newRow && newRow < rows && 0 <= y && y < cols &&
matrix[newRow][y] > matrix[row][newCol]) {
//bug fix: //add new distance matrix[x][y] instead of 1
maxDist = Math.max(maxDist, dfs(matrix, newRow, y, dist + matrix[newRow][y]));
}
}
return maxDist;
}
public static void main(String[] args) {
LongestIncreasingPath lIP = new LongestIncreasingPath();
int[][] nums = { { 9, 9, 4 },
{ 6, 6, 8 },
{ 2, 2, 1 }
};
//printout test case 1
System.out.println(lIP.longestIncreasingPath(nums));
nums = new int[][]{ { 5, 6, 7 },
{ 4, 9, 8 },
{ 3, 2, 1 }
};
//printout test case 2
System.out.println(lIP.longestIncreasingPath(nums));
}
}
public class TestClass {
private static int maxOccurence(int a[]) {
int max = 0;
int count = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
count++;
max = Math.max(max, count);
}
}
count = 0;
}
return max + 1;
}
public static void main(String[] args) {
int a[] = { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
System.out.println(maxOccurence(a));
}
}
This program counts, for each element of an array, the number of times that the element appears; then, it returns the maximum value. In my example, the program prints "5", since element "4" occurs 5 times. How can the element also be printed? In this case, the output of the program would be "4 : 5".
In Java you can write
int[] a = {3, 3, 4, 2, 4, 4, 2, 4, 4};
Map<Integer, Long> countMap = IntStream.of(a).boxed()
.collect(groupingBy(i -> i, counting()));
Map.Entry<Integer, Long> first = countMap.entrySet().stream()
.sorted(comparing(Map.Entry<Integer, Long>::getValue).reversed())
.findFirst().orElseThrow(AssertionError::new);
System.out.println(first.getKey()+":"+first.getValue());
This prints
4:5
[ANSWERED WHEN TAG WAS C#]
It seems to be a nice solution :
public static class TestClass
{
public static void PrintMaxOccurence(int[] a)
{
var maxOccurenceGroup = a.ToList().GroupBy(s => s)
.OrderByDescending(s => s.Count())
.First();
Console.WriteLine(maxOccurenceGroup.Key + " occured " + maxOccurenceGroup.Count() + " times.");
Console.ReadKey();
}
}
class Program
{
public static void main(String[] args)
{
var a = new[] { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
TestClass.PrintMaxOccurence(a);
}
}
Feel free to ask help if needed.
In C# you have to declare variable as int[] a; but not int a[];
static void Main(string[] args)
{
int[] a = new[] { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
PrintMaxOccurence(a);
}
private static void PrintMaxOccurence(int[] a)
{
var result = (from item in a
group item by item into x
orderby x.Count() descending
select new { Element = x.Key, OccurenceCount = x.Count() }).First();
Console.WriteLine("{0} : {1}", result.Element, result.OccurenceCount);
}
We can as well solve the problem using hashtable as follows.
import java.util.Hashtable;
public class MaxOcurr {
public static void main(String[] args) {
Hashtable<Integer,Integer> table = new Hashtable<Integer, Integer>();
int maxCount = 0;
int maxValue = -1;
int a[] = {1,3,2,5,3,6,8,8,8,6,6,7,5,6,4,5,6,4,6,4,1,3,2,6,9,2};
for (int i = 0; i < a.length; i++) {
if (table.containsKey(a[i])) {
table.put(a[i], table.get(a[i])+1);
} else {
table.put(a[i],1);
}
if (table.get(a[i]) > maxCount) {
maxCount = table.get(a[i]);
maxValue = a[i];
}
}
System.out.println(maxValue +":"+ maxCount);
}
}
I am trying to implement a convolution method taking two vectors: an image; and a kernel. My problem is that i don't know how to calculate the index of the image neighbour element when I "slide" the kernel over the image vector. For example, with two identical vectors {0, 1, 2, 3, 4, 5, 6, 7, 8} I would like to achieve the following result:
My code so far is as follows:
public int[] convolve(int[] image, int[] kernel)
{
int imageValue;
int kernelValue;
int outputValue;
int[] outputImage = new int[image.length()];
// loop through image
for(int i = 0; i < image.length(); i++)
{
outputValue = 0;
// loop through kernel
for(int j = 0; j < kernel.length(); j++)
{
neighbour = ?;
// discard out of bound neighbours
if (neighbour >= 0 && neighbour < imageSize)
{
imageValue = image[neighbour];
kernelValue = kernel[j];
outputValue += imageValue * kernelValue;
}
}
output[i] = outputValue;
}
return output;
}
As i + j - (kernel.length / 2) may be too short for an answer:
public class Convolution
{
public static void main(String[] args)
{
int image[] = { 0,1,2,3,4,5,6,7,8 };
int kernel[] = { 0,1,2,3,4,5,6,7,8 };
int output[] = convolve(image, kernel);
for (int i=0; i<image.length; i++)
{
System.out.printf(output[i]+" ");
}
}
public static int[] convolve(int[] image, int[] kernel)
{
int[] output = new int[image.length];
// loop through image
for(int i = 0; i < image.length; i++)
{
System.out.println("Compute output["+i+"]");
int outputValue = 0;
// loop through kernel
for(int j = 0; j < kernel.length; j++)
{
int neighbour = i + j - (kernel.length / 2);
// discard out of bound neighbours
if (neighbour >= 0 && neighbour < image.length)
{
int imageValue = image[neighbour];
int kernelValue = kernel[j];
outputValue += imageValue * kernelValue;
System.out.println("image["+neighbour+"] and kernel["+j+"]");
}
}
output[i] = outputValue;
}
return output;
}
}
Note that this only works properly when the kernel has an odd length. In fact, what you are doing there is to move the center of the kernel through the image space (this is where the kernel.length/2 comes from). For even length kernels, like 0 1 2 3, you would have to decide whether you wanted to include...
0 1 2 3 4 (image)
3 <- This line and/or ...
2 3
1 2 3
0 1 2 3
0 1 2 3
0 1 2
0 1
0 <- ... this line
Sounds to me like you want something like a slider:
static class Slider implements Iterable<List<Integer>> {
final List<Integer> kernel;
final int imageWidth;
final int center;
public Slider(int imageWidth, int kernelWidth) {
// Build my kernel offsets list.
this.kernel = new ArrayList<>(kernelWidth);
for (int i = 0; i < kernelWidth; i++) {
kernel.add(i, i);
}
// Which kernel cell is in the center.
center = kernelWidth / 2;
// Remember the image width.
this.imageWidth = imageWidth;
}
#Override
public Iterator<List<Integer>> iterator() {
return new Iterator<List<Integer>>() {
int x = 0;
#Override
public boolean hasNext() {
return x < imageWidth;
}
#Override
public List<Integer> next() {
List<Integer> slice = kernel.subList(Math.max(0, center - x), Math.min(kernel.size(), center - x + kernel.size()));
x += 1;
return slice;
}
};
}
}
public void test() {
List<Integer> image = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> kernel = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8);
// Keep track of image position.
int x = 0;
for (List<Integer> slice : new Slider(image.size(), kernel.size())) {
System.out.println(slice);
int outputValue = 0;
int imageValue = image.get(x++);
for (Integer o : slice) {
int kernelValue = kernel.get(o);
outputValue += imageValue * kernelValue;
}
System.out.println("outputValue=" + outputValue);
}
}
I am trying to find the contiguous subarray within an array which has the largest sum. So, for the array
{5, 15, -30, 10, -5, 40, 10}
the maximum sum possible using those numbers contiguously would be 55, or (10 + (-5) + 40 + 10) = 55. The program below outputs the maximum sum of 55, however, the problem I am trying to figure out is how to print the sequence that produces this 55. In other words, how can I print out the 10, -5, 40, and 10?
public static void main(String[] args) {
int[] arr = {5, 15, -30, 10, -5, 40, 10};
System.out.println(maxSubsequenceSum(arr));
}
public static int maxSubsequenceSum(int[] X) {
int max = X[0];
int sum = X[0];
for (int i = 1; i < X.length; i++) {
sum = Math.max(X[i], sum + X[i]);
max = Math.max(max, sum);
}
return max;
}
I was thinking of creating an ArrayList to store the sum values at every index of i, so the ArrayList would look like (5, 20, -10, 10, 5, 45, 55). And then I was planning on clearing the ArrayList from index 0 to the first negative number in the list, however, this only solves the problem for this specific example, but if I change the original array of numbers, this solution won't work.
You can replace Math.Max functions by if statements and update start and end index of the best subarray. Pascal version:
if X[i] > sum + X[i] then begin
sum := X[i];
start := i;
end
else
sum := sum + X[i];
if max < sum then begin
max := sum;
finish := i;
end;
You can track the starting and ending indexes of the current best subarray in your loop. Instead of using max() to compute sumand max, just do the following :
int sum_start = 0, sum_end = 0, start = 0, end = 0;
// In the for loop
if (X[i] > sum + X[i]) {
sum = X[i];
sum_start = i;
sum_end = i;
} else {
++sum_end;
}
if (sum > max) {
start = sum_start;
end = sum_end;
max = sum;
}
there is an o(n) solution, a single for loop through the array and reset your sub-sequence whenever your current total is below 0.
{5, 15, -30, 10, -5, 40, 10}
5 + 15 = 20
20 - 30 = -10 (reset sub-sequence)
10 -5 +40 +10 = 55
end. 55 is max sub-sequence
edit: to get subsequence...
whenever you change max, update your subsequence
current left index changes only when u reset
current right index changes every iteration
new max -> save current left and right index...
It can be done by capturing the start and end while identifying maximum sub-array as follows:
Code
package recursion;
import java.util.Arrays;
public class MaximumSubArray {
private static SubArray maxSubArray(int[] values, int low, int high) {
if (low == high) {
// base condition
return new SubArray(low, high, values[low]);
} else {
int mid = (int) (low + high) / 2;
// Check left side
SubArray leftSubArray = maxSubArray(values, low, mid);
// Check right side
SubArray rightSubArray = maxSubArray(values, mid + 1, high);
// Check from middle
SubArray crossSubArray = maxCrossSubArray(values, low, mid, high);
// Compare left, right and middle arrays to find maximum sub-array
if (leftSubArray.getSum() >= rightSubArray.getSum()
&& leftSubArray.getSum() >= crossSubArray.getSum()) {
return leftSubArray;
} else if (rightSubArray.getSum() >= leftSubArray.getSum()
&& rightSubArray.getSum() >= crossSubArray.getSum()) {
return rightSubArray;
} else {
return crossSubArray;
}
}
}
private static SubArray maxCrossSubArray(int[] values, int low, int mid,
int high) {
int sum = 0;
int maxLeft = low;
int maxRight = high;
int leftSum = Integer.MIN_VALUE;
for (int i = mid; i >= low; i--) {
sum = sum + values[i];
if (sum > leftSum) {
leftSum = sum;
maxLeft = i;
}
}
sum = 0;
int rightSum = Integer.MIN_VALUE;
for (int j = mid + 1; j <= high; j++) {
sum = sum + values[j];
if (sum > rightSum) {
rightSum = sum;
maxRight = j;
}
}
SubArray max = new SubArray(maxLeft, maxRight, (leftSum + rightSum));
return max;
}
static class SubArray {
private int start;
private int end;
private int sum;
public SubArray(int start, int end, int sum) {
super();
this.start = start;
this.end = end;
this.sum = sum;
}
public int getStart() { return start; }
public void setStart(int start) { this.start = start; }
public int getEnd() { return end; }
public void setEnd(int end) { this.end = end; }
public int getSum() { return sum; }
public void setSum(int sum) { this.sum = sum; }
#Override
public String toString() {
return "SubArray [start=" + start + ", end=" + end + ", sum=" + sum + "]";
}
}
public static final void main(String[] args) {
int[] values = { 5, 15, -30, 10, -5, 40, 10 };
System.out.println("Maximum sub-array for array"
+ Arrays.toString(values) + ": " + maxSubArray(values, 0, 6));
}
}
Output
Maximum sub-array for array[5, 15, -30, 10, -5, 40, 10]: SubArray [start=3, end=6, sum=55]
Solution can be downloaded from https://github.com/gosaliajigar/Programs/blob/master/src/recursion/MaximumSubArray.java
Two subarray are
[1, 2, 3]
and [4, 9] excluding the negative number
The max sub array here is [ 4, 5]
so the output is 9
Here is the code
public class MaxSubArray{
static void sumM(int a[], int n){
int s1 = Integer.MAX_VALUE;
int k = Integer.MAX_VALUE;
int sum = 0;
int s2 = 0;
for(int i=0;i<n;i++){
if(a[i]<s1){
if(a[i]<0){
k = Math.min(a[i],s1);
}
}
if(a[i]>k){
sum+=a[i];
}
if(a[i]<k){
if(a[i]<0){
continue;
}
s2+=a[i];
}
}
if(sum>s2){
System.out.println(sum);
}
else{
System.out.println(s2);
}
}
public static void main(String[] args){
int a[] = {1,2,3,-7,4,5};
int n = a.length;
sumM(a,n);
}
}
public static int kadane(int[] A) {
int maxSoFar = 0;
int maxEndingHere = 0;
// traverse the given array
for (int i: A) {
// update the maximum sum of subarray "ending" at index `i` (by adding the
// current element to maximum sum ending at previous index `i-1`)
maxEndingHere = maxEndingHere + i;
// if the maximum sum is negative, set it to 0 (which represents
// an empty subarray)
maxEndingHere = Integer.max(maxEndingHere, 0);
// update the result if the current subarray sum is found to be greater
maxSoFar = Integer.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
var maxSequence = function(arr){
// ...
if (arr.every((ele) => ele >= 0)) {
return arr.reduce((sum, ele) => sum + ele, 0);
} else if (arr.every((ele) => ele < 0)) {
return 0;
//for me the maximum would be the biggest negative number
//arr.reduce((max, elm) => (max > elm ? max : elm))
} else if (arr === [0]) {
return 0;
} else {
let maxSum = [];
let currentSum = 0;
for (let i = 0; i < arr.length; i++) {
currentSum = Math.max(arr[i], currentSum + arr[i]);
maxSum.push(currentSum);
}
return maxSum.reduce((max, elm) => (max > elm ? max : elm));
}
}
you need to sum all possible sub array. to do that, you can do this code
public static int maxSubsequenceSum(int[] X) {
int max = 0;
boolean max_init = false;
int max_from=0;
int max_to=0; // this is not included
for (int i = 0; i < X.length; i++) {
for (int j = i + 1; j < X.length + 1; j++) {
int total = 0;
for (int k = i; k < j; k++) {
total += X[k];
}
if (total > max || !max_init){
max = total;
max_init = true;
max_from = i;
max_to = j;
}
}
}
for (int i=max_from;i<max_to;i++)
System.out.print(X[i]+",");
System.out.println();
return max;
}
I am currently developing a class to represent matrices, it represents any general mxn matrix. I have worked out addition and scalar multiplication but I am struggling to develop the multiplication of two matrices. The data of the matrix is held in a 2D array of doubles.
The method looks a little bit like this:
public Matrix multiply(Matrix A) {
////code
}
It will return the product matrix. This is multiplication on the right. So, if I called A.multiply(B) then it would return the matrix AB, with B on the right.
I don't yet need to worry about checking whether the multiplication is defined on the given matrices, I can assume that I will be given matrices of the correct dimensions.
Does anyone know of an easy algorithm, possibly even in pseudocode to carry out the multiplication process?
Mathematically the Product of Matrices A (l x m) and B (m x n) is defined as a Matrix C (l x n) consisting of the elements:
m
c_i_j = ∑ a_i_k * b_k_j
k=1
So if you're not too much up for speed you might be happy with the straight forward O(n^3) implementation:
for (int i=0; i<l; ++i)
for (int j=0; j<n; ++j)
for (int k=0; k<m; ++k)
c[i][j] += a[i][k] * b[k][j]
If instead you're up for speed you might want to check for other alternatives like Strassen algorithm (see: Strassen algorithm).
Nevertheless be warned - especially if you're multiplying small matrices on modern processor architectures speed heavily depends on matrix data and multiplication order arranged in a way to make best use of in cache lines.
I strongly doubt there will be any chance to influence this factor from withing a vm, so I'm not sure if this is to be taken into consideration.
Java. Matrix multiplication.
Here is the "code to carry out the multiplication process". Tested with matrices of different size.
public class Matrix {
/**
* Matrix multiplication method.
* #param m1 Multiplicand
* #param m2 Multiplier
* #return Product
*/
public static double[][] multiplyByMatrix(double[][] m1, double[][] m2) {
int m1ColLength = m1[0].length; // m1 columns length
int m2RowLength = m2.length; // m2 rows length
if (m1ColLength != m2RowLength) return null; // matrix multiplication is not possible
int mRRowLength = m1.length; // m result rows length
int mRColLength = m2[0].length; // m result columns length
double[][] mResult = new double[mRRowLength][mRColLength];
for (int i = 0; i < mRRowLength; i++) { // rows from m1
for (int j = 0; j < mRColLength; j++) { // columns from m2
for (int k = 0; k < m1ColLength; k++) { // columns from m1
mResult[i][j] += m1[i][k] * m2[k][j];
}
}
}
return mResult;
}
public static String toString(double[][] m) {
String result = "";
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
result += String.format("%11.2f", m[i][j]);
}
result += "\n";
}
return result;
}
public static void main(String[] args) {
// #1
double[][] multiplicand = new double[][]{
{3, -1, 2},
{2, 0, 1},
{1, 2, 1}
};
double[][] multiplier = new double[][]{
{2, -1, 1},
{0, -2, 3},
{3, 0, 1}
};
System.out.println("#1\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
// #2
multiplicand = new double[][]{
{1, 2, 0},
{-1, 3, 1},
{2, -2, 1}
};
multiplier = new double[][]{
{2},
{-1},
{1}
};
System.out.println("#2\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
// #3
multiplicand = new double[][]{
{1, 2, -1},
{0, 1, 0}
};
multiplier = new double[][]{
{1, 1, 0, 0},
{0, 2, 1, 1},
{1, 1, 2, 2}
};
System.out.println("#3\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
}
}
Output:
#1
12.00 -1.00 2.00
7.00 -2.00 3.00
5.00 -5.00 8.00
#2
0.00
-4.00
7.00
#3
0.00 4.00 0.00 0.00
0.00 2.00 1.00 1.00
In this answer, I created a class named Matrix, and another class is known as MatrixOperations which defines the various operations that can be performed on matrices (except for row operations of course). But I will extract the code for multiplication from MatrixOperations. The full project can be found on my GitHub page here.
Below is the definition of the Matrix class.
package app.matrix;
import app.matrix.util.MatrixException;
public class Matrix {
private double[][] entries;
public void setEntries(double[][] entries) {
this.entries = entries;
}
private String name;
public double[][] getEntries() {
return entries;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public class Dimension {
private int rows;
private int columns;
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getColumns() {
return columns;
}
public void setColumns(int columns) {
this.columns = columns;
}
public Dimension(int rows, int columns) {
this.setRows(rows);
this.setColumns(columns);
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Dimension){
return (this.getColumns() == ((Dimension) obj).getColumns()) && (this.getRows() == ((Dimension) obj).getRows());
}
return false;
}
}
private Dimension dimension;
public Dimension getDimension() {
return dimension;
}
public void setDimension(Dimension dimension) {
this.dimension = dimension;
}
public Matrix(int dimension, String name) throws MatrixException {
if (dimension == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else this.setEntries(new double[Math.abs(dimension)][Math.abs(dimension)]);
this.setDimension(new Dimension(dimension, dimension));
this.setName(name);
}
public Matrix(int dimensionH, int dimensionV, String name) throws MatrixException {
if (dimensionH == 0 || dimensionV == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else this.setEntries(new double[Math.abs(dimensionH)][Math.abs(dimensionV)]);
this.setDimension(new Dimension(dimensionH, dimensionV));
this.setName(name);
}
private static final String OVERFLOW_ITEMS_MSG = "The values are too many for the matrix's specified dimensions";
private static final String ZERO_UNIT_DIMENSION = "Zero cannot be a value for a dimension";
public Matrix(int dimensionH, int dimensionV, String name, double... values) throws MatrixException {
if (dimensionH == 0 || dimensionV == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else if (values.length > dimensionH * dimensionV) throw new MatrixException(Matrix.OVERFLOW_ITEMS_MSG);
else this.setEntries(new double[Math.abs(dimensionH)][Math.abs(dimensionV)]);
this.setDimension(new Dimension(dimensionH, dimensionV));
this.setName(name);
int iterator = 0;
int j;
for (int i = 0; i < dimensionH; i++) {
j = 0;
while (j < dimensionV) {
this.entries[i][j] = values[iterator];
j++;
iterator++;
}
}
}
public Matrix(Dimension dimension) throws MatrixException {
this(dimension.getRows(), dimension.getColumns(), null);
}
public static Matrix identityMatrix(int dim) throws MatrixException {
if (dim == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
double[] i = new double[dim * dim];
int constant = dim + 1;
for (int j = 0; j < i.length; j = j + constant) {
i[j] = 1.0;
}
return new Matrix(dim, dim, null, i);
}
public String toString() {
StringBuilder builder = new StringBuilder("Matrix \"" + (this.getName() == null ? "Null Matrix" : this.getName()) + "\": {\n");
for (int i = 0; i < this.getDimension().getRows(); i++) {
for (int j = 0; j < this.getDimension().getColumns(); j++) {
if (j == 0) builder.append("\t");
builder.append(this.entries[i][j]);
if (j != this.getDimension().getColumns() - 1)
builder.append(", ");
}
if (i != this.getDimension().getRows()) builder.append("\n");
}
builder.append("}");
return builder.toString();
}
public boolean isSquare() {
return this.getDimension().getColumns() == this.getDimension().getRows();
}
}
and here is the code method for matrix multiplication from MatrixOperations
public static Matrix multiply(Matrix matrix1, Matrix matrix2) throws MatrixException {
if (matrix1.getDimension().getColumns() != matrix2.getDimension().getRows())
throw new MatrixException(MATRIX_MULTIPLICATION_ERROR_MSG);
Matrix retVal = new Matrix(matrix1.getDimension().getRows(), matrix2.getDimension().getColumns(), matrix1.getName() + " x " + matrix2.getName());
for (int i = 0; i < matrix1.getDimension().getRows(); i++) {
for (int j = 0; j < matrix2.getDimension().getColumns(); j++) {
retVal.getEntries()[i][j] = sum(arrayProduct(matrix1.getEntries()[i], getColumnMatrix(matrix2, j)));
}
}
return retVal;
}
and below again are the codes for methods sum, arrayProduct, and getColumnMatrix
private static double sum(double... values) {
double sum = 0;
for (double value : values) {
sum += value;
}
return sum;
}
private static double[] arrayProduct(double[] arr1, double[] arr2) throws MatrixException {
if (arr1.length != arr2.length) throw new MatrixException("Array lengths must be the same");
double[] retVal = new double[arr1.length];
for (int i = 0; i < arr1.length; i++) {
retVal[i] = arr1[i] * arr2[i];
}
return retVal;
}
private static double[] getColumnMatrix(Matrix matrix, int col) {
double[] ret = new double[matrix.getDimension().getRows()];
for (int i = 0; i < matrix.getDimension().getRows(); i++) {
ret[i] = matrix.getEntries()[i][col];
}
return ret;
}
Try this code for multiple any dimensional array and print it. Think this is more simple and anyone can understand this.
public class Test {
public static void main(String[] args) {
int[][] array1 = {
{1, 4, -2},
{3, 5, -6},
{4, 5, 2}
};
int[][] array2 = {
{5, 2, 8, -1},
{3, 6, 4, 5},
{-2, 9, 7, -3}
};
Test test = new Test();
test.printArray(test.multiplication(array1, array2));
}
private int[][] multiplication(int[][] array1, int[][] array2) {
int r1, r2, c1, c2;
r1 = array1.length;
c1 = array1[0].length;
r2 = array2.length;
c2 = array2[0].length;
int[][] result;
if (c1 != r2) {
System.out.println("Error!");
result = new int[0][0];
} else {
result = new int[r1][c2];
for (int i = 0; i < r1; i++) { //2
for (int j = 0; j < c2; j++) { //4
for (int k = 0; k < c1; k++) {
result[i][j] += array1[i][k] * array2[k][j];
}
}
}
}
return result;
}
private void printArray(int[][] array) {
for (int[] arr : array) {
for (int element : arr) {
System.out.print(element + " ");
}
System.out.println();
}
}
}