Question #3 of 3
QUESTION #3:
Write a Java method with the following method signature that takes a String and
returns a String formatted so that it satisfies the requirements below. It may
need to insert newlines and/or delete spaces.
Method Signature:
public static String wrapText(String text, int maxCharsPerLine)
Definitions and Assumptions:
A word is a nonempty sequence of characters that contains no spaces and no newlines.
Lines in the return String are separated by the newline character, ‘\n’.
Words on each line are separated by spaces. Assume that the String argument does
not contain any whitespace characters other than spaces and newlines.
Requirements:
1. Newlines in the String argument are preserved.
2. Words in the return String are separated by either a single space or by one or
more newlines.
3. Lines in the return String do not start or end with any spaces.
4. When constructing the return String from the String argument, each word in the
String argument with at most maxCharsPerLine characters should not be broken up.
Each word in the String argument with more than maxCharsPerLine characters should
be broken up so that all of the other requirements are satisfied.
5. The String argument may contain lines longer than maxCharsPerLine. Newlines
should be added so that each line in the return String has at most maxCharsPerLine
characters. To determine where newlines should be added, try to fit as many words
as possible on a line (while keeping line length at most maxCharsPerLine and
satisfying the other requirements) before starting a new line.
Solution:
import java.util.ArrayList; import java.util.List; public class Q3_FormatString { public static List<String> splitLongWord(String word, int max, int offset) { List<String> result = new ArrayList<String>(); for (int beginIndex = 0, endIndex = 0; beginIndex < word.length(); beginIndex = endIndex) { endIndex = beginIndex + max - offset > word.length() ? word.length() : beginIndex + max - offset; result.add(word.substring(beginIndex, endIndex)); offset = 0; } return result; } public static String wrapText(String text, int maxCharsPerLine) { String[] words = text.split(" |\n"); StringBuilder result = new StringBuilder(); int strLen = 0; for (String word : words) { if (word == null || word.isEmpty()) continue; if (word.length() > maxCharsPerLine) { if (strLen > 0) { result.append(" "); strLen += " ".length(); } List<String> splittedWords = splitLongWord(word, maxCharsPerLine - "\n".length(), strLen); int counter = 0; for (String splittedWord : splittedWords) { String symbol = "\n"; if (++counter == splittedWords.size()) { strLen = splittedWord.length(); symbol = ""; } result.append(splittedWord + symbol); } continue; } if (strLen + word.length() + 1 >= maxCharsPerLine) { result.append('\n'); strLen = 0; } else if (strLen > 0) { result.append(" "); strLen += " ".length(); } result.append(word); strLen += word.length(); } return result.toString(); } public static void main(String[] args) { int maxLineLength = 20; System.out.println(wrapText("#1. The top US general in the MiddleEastToldTeportersThatHeHasReceivedNoSpecificDirectionInThe wake of Monday's ", maxLineLength)); System.out.println(wrapText("#2. a b c d e f g h i j k l", maxLineLength)); System.out.println(wrapText("#3. InTheString a b c d e f", maxLineLength)); System.out.println(wrapText("#4. a b c d e f InTheString", maxLineLength)); System.out.println(wrapText("#5. a b", maxLineLength)); System.out.println(wrapText(" #6 ", maxLineLength)); } }
Output:
#1. The top US general in the Midd leEastToldTeporters ThatHeHasReceivedNo SpecificDirectionIn The wake of Monday's #2. a b c d e f g h i j k l #3. InTheString a b c d e f #4. a b c d e f InTheString #5. a b #6