I am trying to find all adjacent elements in the matrix. Adjacent refers to elements being right beside each other either horizontal, vertical and diagonal elements. However it is giving me java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5. I am not sure why, any help would be much appreciated! Also the program needs to be recursive !
class matrixAdjacent
{
public static void main(String[] args)
{
char grid[][] = {{'0','0','0','1','1','0','1','1','0','0','0','1','1','1','0','1','1','1','0','1'},
{'1','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1','1','1','1','1'},
{'0','1','0','0','1','0','0','0','1','0','1','0','0','0','0','0','0','1','1','1'},
{'1','1','1','0','0','1','0','1','0','0','0','0','1','0','1','1','0','1','1','0'},
{'0','1','1','1','0','1','1','1','0','1','0','0','1','0','1','0','1','1','0','1'}};
ExploreAndLabelColony(grid, 0, 0);
}
private static void ExploreAndLabelColony(char[][] grid, int i, int j)
{
// TODO Auto-generated method stub
if(grid==null)
{
return;
}
if(i==grid.length || j==grid[0].length)
{
return;
}
if (grid[i][j] == '1') //checks if theres a 1 which refers to a colony
{
if (i>0 && i + 1 < grid.length && j>0 && j + 1 < grid[0].length)
{
if (grid[i+1]==grid[j] || grid[i] == grid[j+1] || grid[i-1]==grid[j] || grid[i]==grid[j-1]) //checks if adjacent
{
grid[i][j] = 'A'; //creates a colony
}
}
}
else if(grid[i][j] == '0') //replaces 0 with '-'
{
grid[i][j] = '-';
}
System.out.print(grid[i][j]); //print grid
if(j==grid[0].length-1)
{
System.out.println(); //prints next row
ExploreAndLabelColony(grid,i+1,0); //recurse to increment row
}
ExploreAndLabelColony(grid,i,j+1); //recurse to increment column
}
}
Issues
if (i>0 && i + 1 < grid.length && j>0 && j + 1 < grid[0].length)
{
if (grid[i+1]==grid[j] || grid[i] == grid[j+1] || grid[i-1]==grid[j] || grid[i]==grid[j-1]) //checks if adjacent
{
grid[i][j] = 'A'; //creates a colony
}
}
In the above section of code, j>0 && j + 1 < grid[0].length can not guarantee the access to grid[j].
The check on inner array index can not correctly validate the access to outer array index.
Check adjacent elements
To check adjacent elements, all 4 valid adjacent indices have to be checked
grid[i][j - 1]
grid[i][j + 1]
grid[i - 1][j]
grid[i + 1][j]
In the above 4 checks, please validate the index before making any of the i - 1, i + 1, j - 1, j + 1 access.
For the given cell with coordinates i, j the adjacent elements are in the square:
[i - 1][j - 1], [i - 1][j], [i - 1][j + 1]
[i ][j - 1], CURR_CELL, [i ][j + 1]
[i + 1][j - 1], [i + 1][j], [i + 1][j + 1]
Additional limitations may be applied using Math.min, Math.max functions and adjacent cells can be detected as follows:
if (grid[i][j] == '1') { //checks if theres a 1 which refers to a colony
out: // label to break
for (int ii = Math.max(i - 1, 0), in = Math.min(grid.length, i + 2); ii < in; ii++) {
for (int jj = Math.max(j - 1, 0), jn = Math.min(grid[0].length, j + 2); jj < jn; jj++) {
if (ii == i && jj == j) {
continue; // skip reference cell
}
if (grid[ii][jj] == '1') {
grid[i][j] = 'A';
break out; // as soon as the first neighbor is found
}
}
}
}
With this change, the output for the given input:
public static void main(String[] args) {
char grid[][] = {
{'0','0','0','1','1','0','1','1','0','0','0','1','1','1','0','1','1','1','0','1'},
{'1','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1','1','1','1','1'},
{'0','1','0','0','1','0','0','0','1','0','1','0','0','0','0','0','0','1','1','1'},
{'1','1','1','0','0','1','0','1','0','0','0','0','1','0','1','1','0','1','1','0'},
{'0','1','1','1','0','1','1','1','0','1','0','0','1','0','1','0','1','1','0','1'}
};
ExploreAndLabelColony(grid, 0, 0);
}
is as follows:
---AA-A1---AA1-AAA-A
A----A---A-----AAAAA
-A--A---A-1------AAA
AAA--A-A----A-AA-AA-
-AA1-AA1-1--1-1-A1-1
Possibly, condition should be fixed to check if adjacent cell is already containing A, or if there are too many neighbors but setting/applying these or any other rules is up to the author.
Problem:
I have 2D array which is filled with numbers. I have to output it in a way that it shows: "*" between neighbours with different values and with " " if values are the same.
Example:
*********
*1 1*3*4*
***** * *
*2 2*3*4*
*********
I have tried many things like creating another array with [Nx2][Mx2] size or System.out.format, but in the end it's never formatted the way I like. Any suggestions how can I solve this?
private static void changeColumn(int[][] secondLayerArr, int n, int m) {
String[][] finalLayerArr = new String[n * 2 - 1][m];
int finalLayerRow = -2;
//second layer output
for (int i = 0; i < n; i++) {
finalLayerRow += 2;
for (int j = 0; j < m; j++) {
if (j < m - 1) {
if (secondLayerArr[i][j] != secondLayerArr[i][j + 1]) {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + "*";
// System.out.print(secondLayerArr[i][j] + "*");
} else {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + " ";
// System.out.print(secondLayerArr[i][j]);
}
} else {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + "*";
//System.out.print(secondLayerArr[i][j]+"*");
}
}
}
printColumn(finalLayerArr);
}
public static void changeRow(String[][] finalLayerArr) {
for (int i = 0; i < finalLayerArr[0].length; i++) {
System.out.print("***");
}
System.out.println();
for (int i = 0; i < finalLayerArr.length; i++) {
System.out.print("*");
for (int j = 0; j < finalLayerArr[0].length; j++) {
if (finalLayerArr[i][j] == null) {
if (finalLayerArr[i - 1][j].equals(finalLayerArr[i + 1][j])) {
finalLayerArr[i][j] = " ";
} else {
finalLayerArr[i][j] = "*";
}
}
System.out.printf("%2s", finalLayerArr[i][j], "");
}
System.out.println();
}
}
It shows something like the result I want but its not formatted like in table.
Loop through the 2d array by first looping through the number of arrays inside the array, then looping through each individual one.
Inside the individual arrays, check if this is the first item in the array. If so, print a *. Then check whether the one before is equal etc.
For the " leave " " between neighbouring rows [which have the same item]", we can store the star line inside a StringBuilder and print it out at the end.
int[][] arr = {{1, 1, 3, 4}, {2, 2, 3, 4}};
int lineLength = arr[0].length * 2 + 1;
for (int i = 0; i < lineLength - 1; i++) {
System.out.print("*");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
int[] current = arr[i];
int before = 0;
StringBuilder str = new StringBuilder();
for (int j = 0; j < current.length; j++) {
int rn = current[j];
if (j == 0) {
System.out.print("*");
System.out.print(rn);
} else {
if (before == rn) {
System.out.print(" ");
System.out.print(rn);
} else {
System.out.print("*");
System.out.print(rn);
}
}
if (i != arr.length - 1 && arr[i + 1][j] == rn) {
str.append("* ");
} else {
str.append("**");
}
before = rn;
}
if (i != arr.length - 1) {
System.out.println();
System.out.println(str.toString());
}
}
System.out.println();
for (int i = 0; i < lineLength - 1; i++) {
System.out.print("*");
}
Which prints:
********
*1 1*3*4
**** * *
*2 2*3*4
********
You could loop through every line that isn't the last, then every letter that isn't the last in that array, and checks if it is equal to the one to the right and the one to the bottom. If it is, print the appropriate thing.
Something along these lines:
public class FormattingArray {
public static void printFormattedInts(int[][] unformattedInts) {
// getting maximum digits per number
int maxDigits = 0;
for (int[] intArray : unformattedInts) {
for (int num : intArray) {
if (lengthOfInt(num) > maxDigits) {
maxDigits = lengthOfInt(num);
}
}
}
// printing first line (purely aesthetic)
System.out.print("*".repeat(unformattedInts[0].length * maxDigits + unformattedInts[0].length + 1));
System.out.println();
// printing each row
for (int row = 0; row < unformattedInts.length - 1; row ++) {
String lowerRow = "*"; // the row to print below this one
System.out.print("*");
for (int i = 0; i < unformattedInts[row].length - 1; i ++) {
if (lengthOfInt(unformattedInts[row][i]) < maxDigits) {
System.out.print("0".repeat(maxDigits - (lengthOfInt(unformattedInts[row][i]))));
}
System.out.print(unformattedInts[row][i]);
if (unformattedInts[row][i] == unformattedInts[row][i + 1]) {
System.out.print(" ");
} else {
System.out.print("*");
}
if (unformattedInts[row][i] == unformattedInts[row + 1][i]) {
lowerRow += " ".repeat(maxDigits);
lowerRow += "*";
} else {
lowerRow += "*".repeat(maxDigits + 1);
}
}
if (lengthOfInt(unformattedInts[row][unformattedInts[row].length - 1]) < maxDigits) {
System.out.print("0".repeat(maxDigits - (lengthOfInt(unformattedInts[row][unformattedInts[row].length - 1]))));
}
System.out.print(unformattedInts[row][unformattedInts[row].length - 1]);
System.out.println("*");
// doing last char
if (unformattedInts[row][unformattedInts[row].length - 1] == unformattedInts[row + 1][unformattedInts[row].length - 1]) {
lowerRow += " ".repeat(maxDigits);
lowerRow += "*";
} else {
lowerRow += "*".repeat(maxDigits + 1);
}
System.out.println(lowerRow);
}
// doing last row
System.out.print("*");
for (int i = 0; i < unformattedInts[unformattedInts.length - 1].length - 1; i ++) {
if (lengthOfInt(unformattedInts[unformattedInts.length - 1][i]) < maxDigits) {
System.out.print("0".repeat(maxDigits - lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[0].length - 1])));
}
System.out.print(unformattedInts[unformattedInts.length - 1][i]);
if (unformattedInts[unformattedInts.length - 1][i] == unformattedInts[unformattedInts.length - 1][i + 1]) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
if (lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1]) < maxDigits) {
System.out.print("0".repeat(maxDigits - lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1])));
}
System.out.print(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1]);
System.out.println("*");
System.out.print("*".repeat(unformattedInts[0].length * maxDigits + unformattedInts[0].length + 1));
System.out.println();
}
public static int lengthOfInt(int num) {
return String.valueOf(num).length();
}
}
Hope this helps :)
You can compose an array of strings consisting of numbers from the first array and their neighboring elements, i. e. spaces and asterisks. Format them if necessary with a leading zeros and appropriate count of neighboring elements. For each row, create two arrays of strings, i. e. elements with their horizontal neighbours and intermediate array with vertical neighbours, plus leading and trailing rows of asterisks. Then flatten them vertically and join elements of the rows into one string horizontally.
Try it online!
int[][] arr1 = {
{1, 1, 3, 3, 4, 6, 5, 6, 8, 75},
{2, 2, 2, 3, 4, 5, 5, 5, 8, 8},
{3, 3, 5, 5, 6, 7, 7, 5, 2, 8}};
// numbers format, digits count
int s = 2;
// formatted array representation
// with neighbouring elements
String[] arr2 = IntStream
// iterate over indices of the rows of the
// array, plus leading row of asterisks
.range(-1, arr1.length)
// for each row create two arrays of strings:
// horizontal neighbours and vertical neighbours
.mapToObj(i -> {
// assume the lengths of the rows are identical
int length = arr1[0].length * s * 2 - s + 2;
String[] asterisks = new String[length];
Arrays.fill(asterisks, "*");
if (i == -1)
// leading row of asterisks
return Stream.of(null, asterisks);
else
// iterate over indices of the elements of the rows,
// add asterisks between neighbours with different
// values and spaces if values are the same
return Stream.of(IntStream.range(0, arr1[i].length)
// horizontal neighbours
.mapToObj(j -> {
// formatted representation
// of the element of the row,
// with a leading zeros if necessary
String val = String.format(
"%0" + s + "d", arr1[i][j]);
if (j == 0)
// leading asterisk
val = "*" + val;
if (j == arr1[i].length - 1)
// trailing asterisk
val += "*";
else
// neighbour element
val += arr1[i][j] == arr1[i][j + 1] ?
" ".repeat(s) : "*".repeat(s);
return val;
}).toArray(String[]::new),
// second array
(i == arr1.length - 1) ?
// trailing row of asterisks
asterisks :
// vertical neighbours
IntStream.range(0, arr1[i].length)
.mapToObj(j -> {
String val = "";
if (j == 0)
// leading asterisk
val = "*";
// neighbour element
val += (arr1[i][j] == arr1[i + 1][j] ?
" ".repeat(s) : "*".repeat(s));
if (j == arr1[i].length - 1)
// trailing asterisk
val += "*";
else
// intermediate asterisks
val += "*".repeat(s);
return val;
}).toArray(String[]::new));
}).flatMap(Function.identity())
// skip first null
.skip(1)
// Stream<Stream<String>>
.map(Arrays::stream)
// join each row into one string
.map(stream -> stream.collect(Collectors.joining()))
.toArray(String[]::new);
// output
Arrays.stream(arr2).forEach(System.out::println);
Output:
****************************************
*01 01**03 03**04**06**05**06**08**75*
************* ** ****** ****** *****
*02 02 02**03**04**05 05 05**08 08*
***************************** ****** *
*03 03**05 05**06**07 07**05**02**08*
****************************************
I need a code for making a Pascal's triangle. This code is for a Right triangle, but I need it to be a Pascal's triangle. It needs to have 10 rows and does have a gap in the middle of the Top and the Bottom.
Can anyone please help me on this? for loops will be fine.
public static int get_pascal(int row, int col) {
if (col == 0 || col == row) {
return 1;
} else {
return get_pascal(row - 1, col - 1) + get_pascal(row - 1, col);
}
}
public static void main(String[] args) {
//row size variable
int rowNum = 5;
levels = new String[rowNum];
int i = 0;
int arIndex = 0;
System.out.println(recurseRow(i, rowNum, arIndex));
System.out.println(" ");
System.out.println(upsideDown(rowNum - 1));
}
//Recursion for row
public static String recurseRow(int i, int rowNum, int arrayIndex) {
if (i == rowNum)
return "";
else {
int k = 0;
int next = i + 1;
String str = recurseCol(i, k);
levels[arrayIndex] = str;
arrayIndex += 1;
return str + "\n" + recurseRow(next, rowNum, arrayIndex);
}
}
//Recursion for column
public static String recurseCol(int i, int k) {
if (k > i)
return "";
else {
int next = k + 1;
return get_pascal(i, k) + " " + recurseCol(i, next);
}
}
//upside down recursion
public static String upsideDown(int index) {
if (index < 0) {
return "";
} else {
String str = levels[index];
index -= 1;
return str + "\n" + upsideDown(index);
}
}
Pascal's triangle - is a triangular array of binomial coefficients where the elements of the first row and column are equal to one, and all other elements are the sum of the previous element in the row and column.
T[i][j] = T[i][j-1] + T[i-1][j];
You can create an iterative method to populate such an array:
public static int[][] pascalsTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
for (int i = 0; i < n; i++) {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the elements of the row
for (int j = 0; j < n - i; j++) {
if (i == 0 || j == 0) {
// elements of the first row
// and column are equal to one
arr[i][j] = 1;
} else {
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
}
}
}
return arr;
}
public static void main(String[] args) {
int n = 10;
System.out.println("n = " + n);
System.out.println("Pascal's triangle:");
int[][] arr = pascalsTriangle(n);
for (int[] row : arr) {
for (int element : row)
System.out.printf("%2d ", element);
System.out.println();
}
}
Output:
n = 10
Pascal's triangle:
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9
1 3 6 10 15 21 28 36
1 4 10 20 35 56 84
1 5 15 35 70 126
1 6 21 56 126
1 7 28 84
1 8 36
1 9
1
See also: Array of binomial coefficients
You can add prefix of multiple spaces where you recursively create a row: instead of
String str = recurseCol(i, k);
you'll have
String str = "";
for (int spaces = 0; spaces < 2 * (rowNum - i - 1); spaces++) {
str += " ";
}
str += recurseCol(i, k);
You also need to format all numbers to have the same width inside recurseCol, for example now all numbers will be 3 digits wide:
return String.format("%3d %s", get_pascal(i, k), recurseCol(i, next));
The resulting code of the modified methods:
//Recursion for row
public static String recurseRow(int i, int rowNum, int arrayIndex) {
if( i == rowNum)
return "";
else {
int k = 0;
int next = i + 1;
String str = "";
for (int spaces = 0; spaces < 2 * (rowNum - i - 1); spaces++) {
str += " ";
}
str += recurseCol(i, k);
levels[arrayIndex] = str;
arrayIndex += 1;
return str + "\n" + recurseRow(next, rowNum, arrayIndex);
}
}
//Recursion for column
public static String recurseCol(int i, int k) {
if(k > i)
return "";
else {
int next = k + 1;
return String.format("%3d %s", get_pascal(i, k), recurseCol(i, next));
}
}
The "magic" numbers 2 and 3 are related to each other: if each number is n-digits wide, then we need to add a prefix to the string consisting of n-1 spaces repeated rowNum - i - 1 times.
There are other methods to achieve these, but I think that the above allows to get the result with minimum modifications.