问题
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.
回答1:
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 :)
回答2:
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
********
this took way too much time
回答3:
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:
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*
****************************************
来源:https://stackoverflow.com/questions/65515159/formatting-2d-array-of-numbers