= Solution
First determine the width of each column by finding the longest rendered <String data type> value in it. Independently determine the number of rows as the largest column size. An empty column has width zero. Then traverse rows first and columns second: render a present entry with spaces on the appropriate side, or render an absent entry as an entire column of spaces. Put one separating space between adjacent columns and a newline after each row. In particular, an exhausted column must not shift later entries into its position.
Here is executable <Java> for the <algorithm>. `Column`, defined in part (e), is an ordinary <list> of `Data`. The <object interface> in part (c) supplies the three queries used below. Each query sees stable content during this call; concurrent changes to formatting are outside this contract.
``
static String replicate(char c, int n) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < n; ++i) s.append(c);
return s.toString();
}
static String printData(List<Column> columns) {
int[] width = new int[columns.size()];
int rows = 0;
for (int c = 0; c < columns.size(); ++c) {
Column column = columns.get(c);
rows = Math.max(rows, column.size());
for (Data d : column)
width[c] = Math.max(width[c], d.length());
}
StringBuilder out = new StringBuilder();
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns.size(); ++c) {
if (c != 0) out.append(' ');
Column column = columns.get(c);
if (r >= column.size()) {
out.append(replicate(' ', width[c]));
} else {
Data d = column.get(r);
String text = d.toString();
String pad = replicate(' ', width[c] - text.length());
out.append(d.leftJustified() ? text + pad : pad + text);
}
}
out.append('\n');
}
return out.toString();
}
``
The <algorithm> uses the stipulated fixed-width characters and assumes entries contain no embedded newlines. If the column widths are $w_0,\ldots,w_{k-1}$ and $k>0$, every emitted row has the same width,
$$
\boxed{\sum_{c=0}^{k-1}w_c+(k-1)\quad\text{characters before its newline}.}
$$
An empty collection, or a collection consisting entirely of empty columns, gives the empty <String data type> value. Spaces at the end of a short last row are harmless and preserve the rectangular layout.
Back to article page