Column Aligned Table
Problem
Every input line is a row of words separated by spaces. Print the rows as a table: the cells of a column are padded on the right with spaces to the width of the widest cell in that column, and the cells of a row are joined with the text ' | '. The last cell of every row is not padded. Rows may have different numbers of cells.
Constraints
- 1 <= rows <= 1000
- words have no spaces
Examples
Input
name age amit 20 bela 7
Output
name | age amit | 20 bela | 7
Solutions
We cannot write the first row before we know the widest cell of a column, so the table is read twice: once to measure and once to print.
/*
* Problem : Process lines.
* Input : Several lines.
* Output : The formatted rows.
* Approach: Two passes over the rows.
* Time : O(total characters)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
// Step 1: First pass: find the widest cell of every column.
String[][] rows = new String[lines.length][];
int columns = 0;
for (int i = 0; i < lines.length; i++) {
rows[i] = lines[i].split("\\s+");
columns = Math.max(columns, rows[i].length);
}
int[] widths = new int[columns];
for (String[] row : rows) {
for (int c = 0; c < row.length; c++) {
widths[c] = Math.max(widths[c], row[c].length());
}
}
// Step 2: Second pass: write every cell, padded to its column width. The last cell of a row is not padded.
String[] output = new String[lines.length];
for (int i = 0; i < rows.length; i++) {
StringBuilder line = new StringBuilder();
for (int c = 0; c < rows[i].length; c++) {
if (c > 0) {
line.append(" | ");
}
line.append(rows[i][c]);
if (c < rows[i].length - 1) {
for (int pad = rows[i][c].length(); pad < widths[c]; pad++) {
line.append(' ');
}
}
}
output[i] = line.toString();
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (2)
- Why are two passes needed?
- Why is the last cell not padded?