patternjavaMinor
Print array of sentences vertically
Viewed 0 times
arrayverticallyprintsentences
Problem
Suppose I have an array of sentences:
[ "How To Format", "put returns between paragraphs", "for linebreak add
2 spaces at end" ]
I want to print it like this:
Here's my code:
Is this easy to understand? Can I make it simpler, such as by using different data structures?
[ "How To Format", "put returns between paragraphs", "for linebreak add
2 spaces at end" ]
I want to print it like this:
How put for
To returns linebreak
Format between add
paragraphs 2
spaces
at
endHere's my code:
public static void solve(String[] sentences) {
int n = sentences.length;
if(n == 0)
return;
List> matrix = new ArrayList>();
int maxLength = Integer.MIN_VALUE;
for(String sentence : sentences) {
List words = Arrays.asList(sentence.split(" "));
maxLength = Math.max(maxLength, words.size());
matrix.add(words);
}
for(int col = 0; col < maxLength; col++) {
for(int row = 0; row < matrix.size(); row++) {
try {
System.out.format("%-15s", matrix.get(row).get(col));
}
catch(IndexOutOfBoundsException e) {
System.out.format("%-15s", "");
}
}
System.out.println();
}
}Is this easy to understand? Can I make it simpler, such as by using different data structures?
Solution
Use if statements rather than try/catch
Your method is understandable, you shouldn't use try catch, instead simply check that the index does not exceed the length.
e.g.
Better Regex
Rather than
This ensures that you get all spaces and don't have an incorrect array length due to splitting on multiple empty spaces in a row. You can read more on Regex here.
Though this only applies if you don't want spaces to delimit words, ever, which is the assumption. The input itself sounds like it has to do with the specifications of the problem, but I simply took it as input and nothing more.
Use two dimensional arrays
You also don't need the list overhead for this.
Simply use a two dimensional of the same size as the original array and make the inner arrays the result of calling the aforementioned
Alternative Implmentation:
Your method is understandable, you shouldn't use try catch, instead simply check that the index does not exceed the length.
e.g.
if (col < matrix.get(row).size()) {
// print what you want
} else {
// print just a space
}Better Regex
Rather than
sentence.split(" "); The regex you want is sentence.split("\\s+)This ensures that you get all spaces and don't have an incorrect array length due to splitting on multiple empty spaces in a row. You can read more on Regex here.
Though this only applies if you don't want spaces to delimit words, ever, which is the assumption. The input itself sounds like it has to do with the specifications of the problem, but I simply took it as input and nothing more.
Use two dimensional arrays
You also don't need the list overhead for this.
Simply use a two dimensional of the same size as the original array and make the inner arrays the result of calling the aforementioned
split() method.public static String[][] convertToWordArray(String[] input) {
String[][] result = new String[input.length][];
for (int i = 0; i < result.length; i++) {
result[i] = input[i].trim().split("\\s+");
}
return result;
}Alternative Implmentation:
public class Format {
public static void main(String[] args) {
String[] target = {
"How To Format",
"put returns between paragraphs",
"for linebreak add 2 spaces at end"
};
printWordsVertically(target);
}
/* These next two methods are relics of my initial implementation
You can adjust for the use of 2d arrays and only need 1 method. */
public static int wordCount(String input) {
return input.trim().split("\\s+").length;
}
public static int longestWordCount(String[] input) {
int result = 0;
for (String s : input) {
if (result < wordCount(s)) {
result = wordCount(s);
}
}
return result;
}
public static void printWordsVertically(String[] input) {
int longestWordCount = longestWordCount(input);
int spacesBetweenColumns = 7; // use needed int, or pass as argument
String formatSpecifier = "%-" + (longestWordCount + spacesBetweenColumns) + "s";
String[][] words = convertToWordArray(input);
for (int i = 0; i < longestWordCount; i++) {
for (int j = 0; j < words.length; j++) {
if (i < words[j].length) {
System.out.printf(formatSpecifier, words[j][i]);
} else {
System.out.printf(formatSpecifier, "");
}
}
System.out.println();
}
}
public static String[][] convertToWordArray(String[] input) {
String[][] result = new String[input.length][];
for (int i = 0; i < result.length; i++) {
result[i] = input[i].trim().split("\\s+");
}
return result;
}
}Code Snippets
if (col < matrix.get(row).size()) {
// print what you want
} else {
// print just a space
}public static String[][] convertToWordArray(String[] input) {
String[][] result = new String[input.length][];
for (int i = 0; i < result.length; i++) {
result[i] = input[i].trim().split("\\s+");
}
return result;
}public class Format {
public static void main(String[] args) {
String[] target = {
"How To Format",
"put returns between paragraphs",
"for linebreak add 2 spaces at end"
};
printWordsVertically(target);
}
/* These next two methods are relics of my initial implementation
You can adjust for the use of 2d arrays and only need 1 method. */
public static int wordCount(String input) {
return input.trim().split("\\s+").length;
}
public static int longestWordCount(String[] input) {
int result = 0;
for (String s : input) {
if (result < wordCount(s)) {
result = wordCount(s);
}
}
return result;
}
public static void printWordsVertically(String[] input) {
int longestWordCount = longestWordCount(input);
int spacesBetweenColumns = 7; // use needed int, or pass as argument
String formatSpecifier = "%-" + (longestWordCount + spacesBetweenColumns) + "s";
String[][] words = convertToWordArray(input);
for (int i = 0; i < longestWordCount; i++) {
for (int j = 0; j < words.length; j++) {
if (i < words[j].length) {
System.out.printf(formatSpecifier, words[j][i]);
} else {
System.out.printf(formatSpecifier, "");
}
}
System.out.println();
}
}
public static String[][] convertToWordArray(String[] input) {
String[][] result = new String[input.length][];
for (int i = 0; i < result.length; i++) {
result[i] = input[i].trim().split("\\s+");
}
return result;
}
}Context
StackExchange Code Review Q#101540, answer score: 5
Revisions (0)
No revisions yet.