Formatting 2d array of numbers

☆樱花仙子☆ 提交于 2021-02-10 17:47:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!