Word Wrap problem ( Space optimized solution )

Given a sequence of words, and a limit on the number of characters that can be put in one line (line width). Put line breaks in the given sequence such that the lines are printed neatly. Assume that the length of each word is smaller than the line width. When line breaks are inserted there is a possibility that extra spaces are present in each line. The extra spaces includes spaces put at the end of every line except the last one.
The problem is to minimize the following total cost.
Total cost = Sum of cost of all lines, where cost of line is = (Number of extra spaces in the line)^2.
For example, consider the following string and line width M = 15
“Geeks for Geeks presents word wrap problem”
Following is the optimized arrangement of words in 3 lines
Geeks for Geeks
presents word
wrap problem
The total extra spaces in line 1 and line 2 are 0 and 2. Space for line 3 is not considered as it is not extra space as described above. So optimal value of total cost is 0 + 2*2 = 4.

Examples:

Input format: Input will consists of array of integers where each array element represents length of each word of string. For example, for string S = “Geeks for Geeks”, input array will be arr[] = {5, 3, 5}.
Output format: Output consists of a series of integers where two consecutive integers represent
starting word and ending word of each line.



Input : arr[] = {3, 2, 2, 5}
Output : 1 1 2 3 4 4
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 3
Line number 3: From word no. 4 to 4

Input : arr[] = {3, 2, 2}
Output : 1 1 2 2 3 3
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 2
Line number 3: From word no. 3 to 3

Approach: We have discussed a Dynamic Programming based solution of word wrap problem. The solution discussed used O(n^2) auxiliary space. The auxiliary space used can be reduced to O(n). The idea is to use two 1-D arrays dp[] and ans[], where dp[i] represents minimum cost of the line in which arr[i] is the first word and ans[i] represents index of last word present in line in which word arr[i] is the first word. Let k represents limit on number of characters in each line. Suppose for any line l the first word in that line is at index i in arr[]. The minimum cost of that line is stored in dp[i]. The last word in that line is at index j in arr[], where j can vary from i to n. Iterate over all values of j and keep track of number of characters added so far in line l. If number of characters are less than k then find cost of current line with these number of characters. Compare this cost with minimum cost find so far for this line in dp[i] and update dp[i] and ans[i] accordingly. Repeat above procedure for each value of i, 1 <= i <= n. The starting and ending words of each line will be at index i and index ans[i], where next value of i for line l+1 is ans[i] + 1.



Implementation:

// C++ program for space optimized
// solution of Word Wrap problem.

#include <bits/stdc++.h>
using namespace std;

// Function to find space optimized
// solution of Word Wrap problem.
void solveWordWrap(int arr[], int n, int k)
{
    int i, j;

    // Variable to store number of
    // characters in given line.
    int currlen;

    // Variable to store possible
    // minimum cost of line.
    int cost;

    // DP table in which dp[i] represents
    // cost of line starting with word
    // arr[i].
    int dp[n];

    // Array in which ans[i] store index
    // of last word in line starting with
    // word arr[i].
    int ans[n];

    // If only one word is present then
    // only one line is required. Cost
    // of last line is zero. Hence cost
    // of this line is zero. Ending point
    // is also n-1 as single word is
    // present.
    dp[n - 1] = 0;
    ans[n - 1] = n - 1;

    // Make each word first word of line
    // by iterating over each index in arr.
    for (i = n - 2; i >= 0; i--) {
        currlen = -1;
        dp[i] = INT_MAX;

        // Keep on adding words in current
        // line by iterating from starting
        // word upto last word in arr.
        for (j = i; j < n; j++) {

            // Update number of characters
            // in current line. arr[j] is
            // number of characters in
            // current word and 1
            // represents space character
            // between two words.
            currlen += (arr[j] + 1);

            // If limit of characters
            // is violated then no more
            // words can be added to
            // current line.
            if (currlen > k)
                break;

            // If current word that is
            // added to line is last
            // word of arr then current
            // line is last line. Cost of
            // last line is 0. Else cost
            // is square of extra spaces
            // plus cost of putting line
            // breaks in rest of words
            // from j+1 to n-1.
            if (j == n - 1)
                cost = 0;
            else
                cost = (k - currlen) * (k - currlen) + dp[j + 1];

            // Check if this arrangement gives
            // minimum cost for line starting
            // with word arr[i].
            if (cost < dp[i]) {
                dp[i] = cost;
                ans[i] = j;
            }
        }
    }

    // Print starting index and ending index
    // of words present in each line.
    i = 0;
    while (i < n) {
        cout << i + 1 << " " << ans[i] + 1 << " ";
        i = ans[i] + 1;
    }
}

// Driver function
int main()
{
    int arr[] = { 3, 2, 2, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int M = 6;
    solveWordWrap(arr, n, M);
    return 0;
}
Output:

1 1 2 3 4 4

Time Complexity: O(n^2)
Auxiliary Space: O(n)




A Programmer and A Machine learning Enthusiast

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.




Article Tags :
Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



4.5 Average Difficulty : 4.5/5.0
Based on 2 vote(s)