public boolean searchSummaryData(String textToFind) {
int fromRow, fromCol;
fromRow = summaryTable.getSelectedRow();
fromCol = summaryTable.getSelectedColumn();
if (fromRow < 0) {
fromRow = 0; //set to start point, first row
}
if (fromCol < 0) {
fromCol = 0;
} else {
fromCol++;//incremental search - look through each columns, then switch to next row
if (fromCol >= summaryTable.getColumnCount()) {
fromCol = 0;
fromRow++;
}
}
for (int i = fromRow; i < summaryTableModel.getRowCount(); i++) {
for (int j = fromCol; j < summaryTableModel.getColumnCount(); j++) {
final Object valueAt = summaryTableModel.getValueAt(i, j); //point to object at i,j
if (valueAt != null) {
textToFind = textToFind.toLowerCase();
if (valueAt.toString().toLowerCase().contains(textToFind)) {
//Map the index of the column/row in the table model at j/i to the index of the column/row in the view.
int convertRowIndexToView = summaryTable.convertRowIndexToView(i);
int convertColIndexToView = summaryTable.convertColumnIndexToView(j);
summaryTable.setRowSelectionInterval(i, i);
summaryTable.setColumnSelectionInterval(j, j);
//Return a rectangle for the cell that lies at the intersection of row and column.
Rectangle rectToScrollTo = summaryTable.getCellRect(convertRowIndexToView, convertColIndexToView, true);
tableSp.getViewport().scrollRectToVisible(rectToScrollTo);
return true;
}
}
}
}
return false;
}
I am having a problem with my search method above. The way I did it, It only allows me to search a particular matched keyword once. While being in the same GUIscreen, if I do a second search, even if a keyword is matched, no result is found. I am pretty sure the last searched index is kept and not reset is the problem, but Im unsure where and how to change this.
You are setting the fromRow and fromCol vars to be the selected row and column. And then you are changing the selection to be where the first result is found. If the second search would have only found things to the left or above the current selection, it won't find anything.
Why don't you just set fromRow and fromCol to be 0, 0 in the first place?
Let's say you have a table of 10 row with 5 columns.
There are matches in:
2, 2
4, 1
9, 0
First time you will find 2, 2.
So next time you start in row 2 and column 3. Your algorithm will only look for values in
column 3 and 4 (4 is the last column of your table).
What you should have is:
first look from cell 2, 3 until cell 2, 4
Then use your loops to start from row 3 and column 0 and increment columns--> no match on row 3
Then increment row to 4 and reset column to 0. As you increment column to 1, you will then find your second match.
etc...
I have not tested yet, but I think that in your inner-loop, you should initiate the increment like this
int j = fromCol
should be replaced by
int j = (i == fromRow ? fromCol : 0);
Related
I'm trying to implement a game where the viable moves are down-left and down-right.
The parameter for the function is for the size of the array, so if you pass 4 it will be a 4 by 4 array.
The starting position is the top row from any column. Every element in the array is a number in the range 1-100, taken from a file. I need to find the resulting value for the most profitable route from any starting column.
My current implementation will compare the right position and left position and move to whichever is higher. The problem is, for example, if the left position is lower in value than the right, but the left position will provide more profit in the long run since it can access higher value elements, my algorithm fails.
Here is a demo:
84 (53) 40 62
*42* 14 [41] 57
76 *47* 80 [95]
If we start at number 53. The numbers enclosed in * are the moves that my algorithm will take, but the numbers enclosed in [] are the moves my algorithm should take.
This is my code:
import java.util.ArrayList;
import java.util.Scanner;
public class bestPathGame{
private int[][] grid;
private int n;
public bestPathGame(int num){
Scanner input = new Scanner(System.in);
n = num;
grid = new int[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
grid[i][j] = input.nextInt();
}
}
}
public static void main(String[] args){
bestPathGame obj = new bestPathGame(Integer.parseInt(args[0]));
obj.bestPath();
}
private boolean moveLeftBetter(int r,int c){
if(c <= 0){
return false;
} else if (c >= n -1 ){
return true;
}
return grid[r][c-1] > grid[r][c+1];
}
public void bestPath(){
ArrayList<Integer> allOptions = new ArrayList<>();
for(int k = 0; k < n; k++){
int row = 0;
int col = k;
int collection = grid[row][col];
while(row < n - 1){
row += 1;
if(moveLeftBetter(row,col)){
col-=1;
} else{
col+=1;
}
collection += grid[row][col];
}
allOptions.add(collection);
}
System.out.println(allOptions.stream().reduce((a,b)->Integer.max(a,b)).get());
}
}
Greedy algorithm vs Dynamic programming
There's an issue with the logic of your solution.
Basically, what you are implemented is a called a greedy algorithm. At each step of iteration, you are picking a result that optimal locally, assuming that this choice will lead to the optimal global result. I.e. your code is based on the assumption that by choosing a local maximum between the two columns, you will get the correct global maximum.
As a consequence, your code in the bestPath() method almost at each iteration will discard a branch of paths based on only one next value. This approach might lead to incorrect results, especially with large matrixes.
Greedy algorithms are rarely able to give an accurate output, usually their result is somewhat close but not precise. As an upper-hand, they run fast, typically in O(n) time.
For this problem, you need to use a dynamic programming (DP).
In short, DP is an enhanced brute-force approach which cashes the results and reuses them instead of recalculating the same values multiple times. And as well, as a regular brute-force DP algorithms are always checking all possible combinations.
There are two major approaches in dynamic programming: tabulation and memoization (take a look at this post for more information).
Tabulation
While implementing a tabulation first you need to create an array which then need to be prepopulated (completely or partially). Tabulation is also called the bottom-up approach because calculation start from the elementary edge cases. Every possible outcome is being computed based on the previously obtained values while iterating over this array. The final result will usually be stored in the last cell (in this case in the last row).
To implement the tabulation, we need to create the matrix of the same size, and copy all the values from the given matrix into it. Then row by row every cell will be populated with the maximum possible profit that could be obtained by reaching this cell from the first row.
I.e. every iteration will produce a solution for a 2D-array, that continuously increases by one row at each step. It'll start from the array that consists of only one first row (no changes are needed), then to get the profit for every cell in the second row it's values has to be combined with the best values from the first row (that will be a valid solution for 2D-array of size 2 * n), and so on. That way, solution gradually develops, and the last row will contain the maximum results for every cell.
That how the code will look like:
public static int getMaxProfitTabulation(int[][] matrix) {
int[][] tab = new int[matrix.length][matrix.length];
for (int row = 0; row < tab.length; row++) { // populating the tab to preserve the matrix intact
tab[row] = Arrays.copyOf(matrix[row], matrix[row].length);
}
for (int row = 1; row < tab.length; row++) {
for (int col = 0; col < tab[row].length; col++) {
if (col == 0) { // index on the left is invalid
tab[row][col] += tab[row - 1][col + 1];
} else if (col == matrix[row].length - 1) { // index on the right is invalid
tab[row][col] += tab[row - 1][col - 1];
} else {
tab[row][col] += Math.max(tab[row - 1][col - 1], tab[row - 1][col + 1]); // max between left and right
}
}
}
return getMax(tab);
}
Helper method responsible for extracting the maximum value from the last row (if you want to utilize streams for that, use IntStream.of(tab[tab.length - 1]).max().orElse(-1);).
public static int getMax(int[][] tab) {
int result = -1;
for (int col = 0; col < tab[tab.length - 1].length; col++) {
result = Math.max(tab[tab.length - 1][col], result);
}
return result;
}
Memoization
The second option is to use Memoization, also called the top-down approach.
As I said, DP is an improved brute-force algorithm and memoization is based on the recursive solution that generates all possible outcomes, that is enhanced by adding a HashMap that stores all previously calculated results for every cell (i.e. previously encountered unique combination of row and column).
Recursion starts with the first row and the base-case of recursion (condition that terminates the recursion and is represented by a simple edge-case for which output is known in advance) for this task is when the recursive call hits the last row row == matrix.length - 1.
Otherwise, HashMap will be checked whether it already contains a result. And if it not the case all possible combination will be evaluated and the best result will be placed into the HashMap in order to be reused, and only the then the method returns.
Note that tabulation is usually preferred over memoization, because recursion has significant limitations, especially in Java. But recursive solutions are sometimes easier to came up with, so it's completely OK to use it when you need to test the idea or to prove that an iterative solution is working correctly.
The implementation will look like that.
public static int getMaxProfitMemoization(int[][] matrix) {
int result = 0;
for (int i = 0; i < matrix[0].length; i++) {
result = Math.max(result, maxProfitHelper(matrix, 0, i, new HashMap<>()));
}
return result;
}
public static int maxProfitHelper(int[][] matrix, int row, int col,
Map<String, Integer> memo) {
if (row == matrix.length - 1) { // base case
return matrix[row][col];
}
String key = getKey(row, col);
if (memo.containsKey(key)) { // if cell was already encountered result will be reused
return memo.get(key);
}
int result = matrix[row][col]; // otherwise result needs to be calculated
if (col == matrix[row].length - 1) { // index on the right is invalid
result += maxProfitHelper(matrix, row + 1, col - 1, memo);
} else if (col == 0) { // index on the left is invalid
result += maxProfitHelper(matrix, row + 1, col + 1, memo);
} else {
result += Math.max(maxProfitHelper(matrix, row + 1, col - 1, memo),
maxProfitHelper(matrix, row + 1, col + 1, memo));
}
memo.put(key, result); // placing result in the map
return memo.get(key);
}
public static String getKey(int row, int col) {
return row + " " + col;
}
Method main() and a matrix-generator used for testing purposes.
public static void main(String[] args) {
int[][] matrix = generateMatrix(100, new Random());
System.out.println("Tabulation: " + getMaxProfitTabulation(matrix));
System.out.println("Memoization: " + getMaxProfitMemoization(matrix));
}
public static int[][] generateMatrix(int size, Random random) {
int[][] result = new int[size][size];
for (int row = 0; row < result.length; row++) {
for (int col = 0; col < result[row].length; col++) {
result[row][col] = random.nextInt(1, 101);
}
}
return result;
}
if we have these numbers in
array [][]
{1, 2, 3, 4},
{1, 2, 20, 4},
{1, 20, 2, 4},
{1, 2, 3, 4},};
it should looks like this
1 0 0 4
0 0 0 0
0 0 0 0
1 0 0 4
but i could output code only like this...
1 0 3 4
1 0 20 4
0 0 0 0
1 0 3 4
and i don't understand how to correct it, please help me,
this is my code.Thanks!
package com.company;
public class Main {
public static void main(String[] args) {
int[][] array2 = {{1, 2, 3, 4},
{1, 2, 20, 4},
{1, 20, 2, 4},
{1, 2, 3, 4},};
int countMax = 0;
int countIndexHorizontal = 0;
int countIndexVertical = 0;
int max = Integer.MIN_VALUE;
int m, k,x;
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
if (array2[i][j] > max) {
max = array2[i][j];
}
}
}
for (k = 0; k < array2.length; k++) {
for (m = 0; m < array2[k].length; m++) {
if (array2[k][m] == max) {
countIndexHorizontal = k;
countIndexVertical = m;
for (x = 0; x < array2.length; x++) {
for (int j = 0; j < array2[x].length; j++) {
if (countIndexVertical == x || j == countIndexHorizontal) {
array2[x][j] = 0;
}
}
}
}
}
}
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j] + " ");
}
System.out.println();
}
}
}
it looks like there are a lot of code and a little of words and site don't allow me to finally post my question and i'm really angry, maybe this text will help me to solve this problem.
Algorithm
This is the part when you only use pen and paper. Basically, I understood the problem as follow:
Given a matrix with n rows and m columns of Integer1:
Find the highest value
All entries in the rows and columns holding the highest value must have its value set at 0
Print the updated matrix
Assumption
I made the following assumptions:
In n is not necessarily equal to m. For example, you can have the array:
Valid Input
1 2 3 4 5 6
7 8 9 10 11 12
7 8 12 5 6 4
which must give, as 12 is the highest value:
Output
1 2 0 4 5 0
0 0 0 0 0 0
0 0 0 0 0 0
The matrix is consistent: every row has m columns and every column has n rows. For example, such input is incorrect:
Incorrect input
1 2 3
7 8 9 10
7 8
Logic
At this stage, you're still using pen, paper and Google only!
In my problem understanding, I splitted in three parts as I thought this is how you understood the problem. This is the mathematics understanding. Now let's convert it into a more Java understanding. First of all, we need to translate some vocabulary:
Mathematics wording | Java wording
--------------------|---------------------
matrix | 2-dimensional array
Integer | int (primitive type)
which gives in Java way:
Given an 2-dimensional int[][] array:
Find the highest value
Find the rows and columns holding the highest value
Update the array by setting the value to 0 for the rows and columns found in 2.
Print the array
In the specific case of my solution, I combine 1. + 2. and I combined 3. + 4.
What you did
Let's open your favorite IDE and compare my analysis with your input:
Find the highest value: OK here: : you use the variable max and scan the matrix to find the maximum value. You also assumed that the matrix could be rectangle (n rows and m columns with n != m). So it's good
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
if (array2[i][j] > max) {
max = array2[i][j];
}
}
}
Find the rows and columns: ERROR here, as mentioned by ccp-beginner, when you found a the highest value, you erase (set to zero) the value for the whole column and whole row but maybe the same highest value was stored somewhere else in this row or column
for (k = 0; k < array2.length; k++) {
for (m = 0; m < array2[k].length; m++) {
if (array2[k][m] == max) {
countIndexHorizontal = k;
countIndexVertical = m;
// additional operation defined in 3.
}
// in ccp-beginner example of
// 2, 2
// 1, 1
// if k=0 and m=0, you'll update the value
// of the first row and first column giving:
// 0, 0
// 0, 1
// but when k=0, m=1, you'll find 0 instead
// of 2 so your program will consider that
// this row / column does not contain the
// highest value
}
}
I assume here the
countIndexHorizontal = row
countIndexVertical = column
So you need to keep track of the rows and columns when you're setting the values to 0.
Update the array: ERROR here (cf ccp-beginner's answer)
for (x = 0; x < array2.length; x++) {
for (int j = 0; j < array2[x].length; j++) {
if (countIndexVertical == x || j == countIndexHorizontal) {
array2[x][j] = 0;
// In your example:
// 1 2 3 4
// 1 2 20 4
// 1 20 2 4
// 1 2 3 4
// and if countIndexVertical=2 and countIndexHorizontal=1
// (the 20 of the second row between 2 and 4), you'll have
// 1 0 3 4
// 1 0 20 4
// 0 0 0 0
// 1 0 3 4
// instead of
// 1 2 0 4
// 0 0 0 0
// 1 20 0 4
// 1 2 0 4
}
}
}
you got confused between countIndexVertical and countIndexHorizontal, as you have
x = row
j = column
You should had (please notice the swapping)
if (countIndexHorizontal == x || j == countIndexVertical) {
array2[x][j] = 0;
}
Print the array: OK here, nothing special to mention
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j] + " ");
}
System.out.println();
}
The problem
Basically, what you need is how to store the rows and the columns containing the highest value. At first, we could be tempted to use array again right, like
int[] rowsContainingHighestValue;
int[] columnsContainingHighestValue;
But you don't know how many highest value you'll encounter so you need something to store multiple value with a dynamic size: I'll use List.
Some Java point
The rowsContainingHighestValue and columnsContainingHighestValue become:
List<Integer> rowsContainingHighestValue = new ArrayList<>();
List<Integer> columnsContainingHighestValue = new ArrayList<>();
You may want to have a look at the following point:
Why List instead of array?
My objects are declared as List but I instantiate2 with ArrayList: What is a Interface and what is a Class
Why I used List<Integer> instead of List<int>
What is the difference between Integer and int
One solution
loop through for the matrix to fetch the maximum value and store all rows and columns holding this value instead of a single row/column combination (countIndexHorizontal and countIndexVertical)
If a new maximum value is found, store it (like you did) AND store the current row and column index
If a value is identical to the current maximum value (e.g. you have 20 twice), then append the row and column index to the existing respective row / column list
loop a second time for updating and printing the value
it's basically combining your two last double-loop: if the scanned element belongs to a row or a column holding the maximum value, then the value must be set at 0 (exactly the way you did but shorter as I already have the list of rows / columns)
once the values are properly updated, just proceed to a simple printing
Which in code gives:
public static void main(String[] args) {
int[][] array2 = {
{1, 2, 3, 4},
{1, 2, 20, 4},
{1, 20, 2, 4},
{1, 2, 3, 4}
};
// find the maximum value and store its position:
// It's List instead of a single value as multiple
// rows and columns can hold the same maximum value
List<Integer> rowsWithMaxValue = new ArrayList<>();
List<Integer> colsWithMaxValue = new ArrayList<>();
int maxValue = Integer.MIN_VALUE;
// First matrix-scan to fetch the maximum value and the
// row(s) and column(s) to set the value at 0
for (int row = 0; row < array2.length; row++) {
for (int col = 0; col < array2[row].length; col++) {
// get the current value
int value = array2[row][col];
// found a new maximum or an existing one?
if (value > maxValue) {
// this is a new maximum value, we can reset
// the list as the previous rows and columns
// are not relevant anymore
maxValue = value;
rowsWithMaxValue = new ArrayList<>();
colsWithMaxValue = new ArrayList<>();
rowsWithMaxValue.add(row);
colsWithMaxValue.add(col);
} else if (value == maxValue) {
// The same value (like 20) is found again
// so multiple rows and columns will have
// their value set at 0
rowsWithMaxValue.add(row);
colsWithMaxValue.add(col);
}
}
}
// Second matrix-scan for updating the values and printing
for (int row = 0; row < array2.length; row++) {
for (int col = 0; col < array2[row].length; col++) {
// is it in a forbidden row? If yes, set the value
// at zero. One of the condition (row or column) is
// enough to have its value set at 0
if (rowsWithMaxValue.contains(row) || colsWithMaxValue.contains(col)) {
array2[row][col] = 0;
}
// Simply print the value
System.out.print(array2[row][col] + " ");
}
System.out.println();
}
}
1Integer in the mathematics meaning: positive or negative number without decimal
2I won't explain instantiation here. Feel free to google it
You can improve the program by changing the condition to
if (countIndexHorizontal == x || j == countIndexVertical)
Your program is deleting the wrong lines for the first 20 it finds (including the other 20).
This change will get you the correct answer for your specific case, but the program is still broken for examples like this
2 2
1 1
The correct output is
0 0
0 0
but it won't work because when it finds the first 2 it will delete the second 2, but the second 2 is still needed to clear the 0 in the bottom right corner. You're going to have to keep a separate data structure for the positions you want to clear. I'll leave that for you to figure out.
Below problem has a list of characters and number of columns as the input. Number of columns is not a constant and can vary with every input.
Output should have all the rows fully occupied except for the last one.
list: a b c d e f g
colums: 3
Wrong:
a b c
d e f
g
Wrong:
a d g
b e
c f
Correct:
a d f
b e g
c
I have tried below:
public static void printPatern(List<Character> list, int cols) {
for (int i = 0; i < cols; i++) {
for (int j = i; j < list.size(); j += cols) {
System.out.print(list.get(j));
}
System.out.println();
}
}
It gives output as (which is wrong):
a d g
b e
c f
I am trying to come with an algorithm to print the correct output. I want to know what are the different ways to solve this problem. Time and Space complexity doesn't matter. Also above method which I tried is wrong because it takes columns as the parameter but that's actually acting as the number of rows.
FYI: This is not a HOMEWORK problem.
Finally able to design the algorithm for this problem
Please refer below java code same
public class puzzle{
public static void main(String[] args){
String list[] = { "a", "b", "c","d","e","f","g","h","i","j" };
int column = 3;
int rows = list.length/column; //Calculate total full rows
int lastRowElement = list.length%column;//identify number of elements in last row
if(lastRowElement >0){
rows++;//add inclomplete row to total number of full filled rows
}
//Iterate over rows
for (int i = 0; i < rows; i++) {
int j=i;
int columnIndex = 1;
while(j < list.length && columnIndex <=column ){
System.out.print("\t"+list[j]);
if(columnIndex<=lastRowElement){
if(i==rows-1 && columnIndex==lastRowElement){
j=list.length; //for last row display nothing after column index reaches to number of elements in last row
}else{
j += rows; //for other rows if columnIndex is less than or equal to number of elements in last row then add j value by number of rows
}
}else {
if(lastRowElement==0){
j += rows;
}else{
j += rows-1; //for column greater than number of element in last row add j = row-1 as last row will not having the column for this column index.
}
}
columnIndex++;//Increase column Index by 1;
}
System.out.println();
}
}
}
This is probably homework; so I am not going to do it for you, but give you some hints to get going. There are two points here:
computing the correct number of rows
computing the "pattern" that you need when looping your list so that you print the expected result
For the first part, you can look into the modulo operation; and for the second part: start iterating your list "on paper" and observe how you are printing the correct result manually.
Obviously, that second part is the more complicated one. It might help if you realize that printing "column by column" is straight forward. So when we take your correct example and print the indexes instead of values, you get:
0 3 6
1 4 7
2 5
Do that repeatedly for different input; and you will soon discover the pattern of indexes that you need to print "row by row".
Assume I had a 2D integer array, mxn.
I want to traverse this array like a sine wave.
In specific, traversal would start from the last row, and the first column, move onto the first row and the second column, move onto the last row and the third column.
I have attached an image to elaborate further.
t:
I only know how to traverse in order, but I was thinking of transposing the columns, changing the starting index of the column at every round, but I couldn't create a consisting loop to do so.
My attempt:
boolean startsAtbottom=true;
//cols become rows, startPoint alternates
for(int i = 0;i<n;i++)
{
if(startsAtbottom)
{
for(int j =m-1;j>-1;j--)
{
System.out.print(myArr[j][i]);
}
startsAtbottom=false;
}
else
{
for(int j =0;j<m;j++)
{
System.out.print(myArr[j][i]);
}
startsAtbottom=true;
}
}
The following code will do what you want. All you want is to change the way you traverse in consecutive iterations.
boolean traverseInOrder=true;
for(int i=0;i<columnCount;i++){
for(int j=0;j<rowCount;j++){
index=j;
if(!traverseInOrder){
index=rowCount-j-1;
}
//access the element
int element=array[i][index];
}
traverseInOrder= !traverseInOrder;
}
Your solution works, and there's nothing wrong with it. However you can get rid of the if by doing this:
for (int i = 0; i < n; i++) {
boolean goingUp = i % 2 == 0;
for (int j = 0; j < m; j++) {
int row = goingUp ? m - 1 - j : j;
System.out.println(myArr[row][i]);
}
}
Starting from your input you have that:
the outer loop index just increments from 0
the inner loop index increments for even columns and decrements for odd columns
you can determine if a number is even or odd by just checking if modulo is 0 (or by checking if (i & 0x01) == 0 but that's irrelevant)
Given this it's quite easy to model that pattern:
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
int value = data[i][i % 2 == 0 ? (cols - j - 1) : j]
}
}
The formula cols - j - 1 allows you to start from the end and go backward (see that with j = 0 you have cols - 1 and with j = cols - 1 you have cols - (cols - 1) - 1 == 0).
Mind that Java is nor column major nor row major, since a bidimensional array is just an array of arrays so according to your real layout you may need to swap indices.
I am trying to iterate through a randomly generated 2d array of 0s, and 1s. In this method which I am stuck on I am trying to see if the subdiagonal has all the same numbers, all 1s, all 0s, or different numbers.
sub diagonal meaning:
110
101
011
The 0s are the subdiagonal.
this is the code I have as of now. I am trying to iterate starting at the last row and counting up to the first row diagonally.
int firstValue= matrix[matrix.length-1][0];
int result = -1;
for(int row = matrix.length-1; row > 0; row--)
{
int column = row;
if(firstValue == matrix[row][column])
{
result = firstValue;
continue;
}
else
{
result = -1;
break;
}
}
if(result== 1)
{
System.out.println("All " + firstValue + "s on the subdiagonal");
}
else if (result == 0)
{
System.out.println("All " + firstValue + "s on the subdiagonal");
}
else
{
System.out.println("Numbers on subdiagonal are different");
}
}
I'm almost certain my issue is with the firstValue and/or the for loop counting up the diagonal.
Any help would be appreciated, thanks much
Your issue seems to be at the following line,
for(int row = matrix.length-1; row > 0; row++) {
...
}
you are doing a
row = matrix.length-1; // row = array length - 1
row++ //this will increase the row's value beyond your array length
Then you will be accessing a index that does not exist causing a ArrayIndexOutOfBoundsException
Edit
what you'd want to do is,
for(int row = matrix.length-1; row >= 0; row--) {
....
}
This way you'd be able to iterate though your array from largest index to the smallest (0).
Edit 2
Let's say Staring array called arr has 4 elements. It'll be structured as below,
arr[0] = "test1";
arr[1] = "test2";
arr[2] = "test3";
arr[3] = "test4";
Array indexes always starts from 0, so the highest index in the above array is 3.
So if you want to iterate from smallest index to the largest, you'd do
for(int i = 0; i < arr.length; i++) {
//i's initial value is 0 and itll increment each time the loop runs
//loop will terminate when i is no longer < 4
System.out.println(arr[i]);
}
and to iterate through the array in reverse order you'd do,
for(int i = (arr.length - 1); i <= 0; i--) {
//i's initial value is (4 - 1) and it'll decrement each time the loop runs
//loop will terminate when i smaller or equal to 0
System.out.println(arr[i]);
}
So we want to check if all of the values in the subdiagonal are the same value, and if they are then we want to print the value that is the same. First we set aside a comparison to check the other indices
int checkValue = arr[0][arr[0].length-1];
This is the last value in the first row. Then we set a flag to catch whenever our index that we are checking matches our first value. We'll set it to false because we'll assume that the values don't match.
boolean flag = false;
Now that we have that, we need to iterate through each row in our array. We will start with the second row (arr[1]) and then we need to check the value one down and one over compared to the last value we checked (arr[1][arr.length - 1 - i]). If our first value (we assigned it's value to checkValue) and the value we are checking are the same, change the flag to true.
for (int i = 1; i < arr.length; i++)
if (arr[i][arr.length - 1 - i] != checkValue)
flag = true;
That'll run through all of the rows in the array. Now we have to check the state of our flag and print out the appropriate response. If the flag is true, print out that the values on the row are the same. Else we will say that the subdiagonal does not match all the way through.
if (!flag)//remember our flag is set to false, double negative equals true.
System.out.println("All of the values on the subdiagonal are the same");
else
System.out.println("All of the values on the subdiagonal are not the same");