Word Wrap to a Fixed Width

medium Files and I/O

Problem

The first line is a width W. All the other lines together form a text (join them with one space). Break the text into lines of at most W characters. Break only at spaces, and put as many words on a line as fit. Every word is at most W characters long. Print the wrapped lines.

Constraints

  • 1 <= W <= 100
  • every word has at most W characters

Examples

Input

10
the quick brown fox

Output

the quick
brown fox

Solutions

Best approachTime O(n)Space O(n)

Greedy filling is optimal for a line count: put the next word on the line if it fits, else start a new line. One pass over the words, O(total length).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several lines.
 * Output  : The wrapped lines.
 * Approach: Greedy by words.
 * Time    : O(n)
 * 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: The first line is the width. The other lines are joined and split into words.
        int width = Integer.parseInt(lines[0]);
        StringBuilder all = new StringBuilder();
        for (int i = 1; i < lines.length; i++) {
            all.append(i == 1 ? "" : " ").append(lines[i]);
        }
        java.util.List<String> result = new java.util.ArrayList<String>();
        StringBuilder current = new StringBuilder();
        for (String word : all.toString().trim().split("\\s+")) {
            // Step 2: Add the word to the current line if it fits (with one space). Otherwise close the line and start a new one.
            if (current.length() == 0) {
                current.append(word);
            } else if (current.length() + 1 + word.length() <= width) {
                current.append(' ').append(word);
            } else {
                result.add(current.toString());
                current = new StringBuilder(word);
            }
        }
        if (current.length() > 0) {
            result.add(current.toString());
        }
        return result.toArray(new String[0]);
    }

    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)
  1. When does a new line start?
  2. Why is the space counted in the length?