Justify the given Text based on the given width of each line

• Difficulty Level : Hard
• Last Updated : 27 Feb, 2020

Given a string str and width of each line as L, the task is to justify the string such that each line of justified text is of length L with help of space (‘ ‘) and the last line should be left-justified.

Examples:

Input: str = “GeeksforGeek is the best computer science portal for geeks.”, L = 16
Output:
GeeksforGeek__is
the_________best
computer_science
portal_______for
geeks.__________

Input: str = “The quick brown fox jumps over the lazy dog.”, L = 11
Output:
The___quick
brown___fox
jumped_over
the____lazy
dogs.______
The symbol _ denotes a space.

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:
The number of spaces between words in each line cannot be computed until a complete set of words in that line is known. We will solve this problem on a line-by-line basis.

1. Split the given text into words
2. Firstly select the words which can be inserted in each line including a space between each word. For that, the sum of length of included words with one space between them must be smaller than or equal to L.
3. Now count the number of spaces needed to make the length of each line L and distribute the spaces evenly.
4. Repeat above steps for next set of words.
5. For the last line spaces must be assigned at the end as the last line must be left-justified.

Below is the implementation of the above approach:

 // C++ program to Justify the given Text// according to the given width of each line  #include "bits/stdc++.h"using namespace std;  // Function to join the words// with spaces spread evenlystring JoinALineWithSpace(    vector& words,    int start, int end,    int num_spaces){      // Number of words in current line    int num_words_curr_line        = end - start + 1;      // String to store the justified text    string line;      for (int i = start; i < end; i++) {          line += words[i];        --num_words_curr_line;          // Count number of current space needed        int num_curr_space            = ceil((double)(num_spaces)                   / num_words_curr_line);          // Insert spaces in string line        line.append(num_curr_space, ' ');          // Delete the spaces inserted in line        num_spaces -= num_curr_space;    }      // Insert word to string line    line += words[end];    line.append(num_spaces, ' ');      // Return justified text    return line;}  // Function that justify the words of// sentence of length of line Lvector JustifyText(    vector& words,    int L){      int curr_line_start = 0;    int num_words_curr_line = 0;    int curr_line_length = 0;      // To store the justified text    vector result;      // Traversing the words array    for (int i = 0; i < words.size(); i++) {          // curr_line_start is the first word        // in the current line, and i is        // used to identify the last word        ++num_words_curr_line;          int lookahead_line_length            = curr_line_length              + words[i].size()              + (num_words_curr_line - 1);          // If by including the words length becomes L,        // then that set of words is justified        // and add the justified text to result        if (lookahead_line_length == L) {              // Justify the set of words            string ans                = JoinALineWithSpace(                    words,                    curr_line_start,                    i,                    i - curr_line_start);              // Store the justified text in result            result.emplace_back(ans);              // Start the current line            // with next index            curr_line_start = i + 1;              // num of words in the current line            // and current line length set to 0            num_words_curr_line = 0;            curr_line_length = 0;        }          // If by including the words such that        // length of words becomes greater than L,        // then hat set is justified with        // one less word and add the        // justified text to result        else if (lookahead_line_length > L) {              // Justify the set of words            string ans                = JoinALineWithSpace(                    words,                    curr_line_start,                    i - 1,                    L - curr_line_length);              // Store the justified text in result            result.emplace_back(ans);              // Current line set to current word            curr_line_start = i;              // Number of words set to 1            num_words_curr_line = 1;              // Current line length set            // to current word length            curr_line_length = words[i].size();        }          // If length is less than L then,        // add the word to current line length        else {            curr_line_length                += words[i].size();        }    }      // Last line is to be left-aligned    if (num_words_curr_line > 0) {        string line            = JoinALineWithSpace(                words,                curr_line_start,                words.size() - 1,                num_words_curr_line - 1);          line.append(            L - curr_line_length                - (num_words_curr_line - 1),            ' ');          // Insert the last line        // left-aligned to result        result.emplace_back(line);    }      // Return result    return result;}  // Function to insert words// of sentencevector splitWords(string str){      vector words;    string a = "";    for (int i = 0; str[i]; i++) {          // Add char to string a        // to get the word        if (str[i] != ' ') {            a += str[i];        }          // If a space occurs        // split the words and        // add it to vector        else {            words.push_back(a);            a = "";        }    }      // Push_back the last word    // of sentence    words.push_back(a);      // Return the vector of    // words extracted from    // string    return words;}  // Function to print justified textvoid printJustifiedText(vector& result){    for (auto& it : result) {        cout << it << endl;    }}  // Function to call the justificationvoid justifyTheText(string str, int L){      vector words;      // Inserting words from    // given string    words = splitWords(str);      // Function call to    // justify the text    vector result        = JustifyText(words, L);      // Print the justified    // text    printJustifiedText(result);}  // Driver Codeint main(){    string str        = "GeeksforGeek is the best"          " computer science portal"          " for geeks.";    int L = 16;      justifyTheText(str, L);      return 0;}
Output:
GeeksforGeek  is
the         best
computer science
portal       for
geeks.

Time Complexity: O(N), where N = length of string

My Personal Notes arrow_drop_up