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 = “GeeksforGeeks 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.
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.
- Split the given text into words
- 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.
- Now count the number of spaces needed to make the length of each line L and distribute the spaces evenly.
- Repeat above steps for next set of words.
- 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 evenly string JoinALineWithSpace( vector<string>& 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 L vector<string> JustifyText( vector<string>& 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<string> 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 sentence vector<string> splitWords(string str) { vector<string> 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 text void printJustifiedText(vector<string>& result)
{ for ( auto & it : result) {
cout << it << endl;
}
} // Function to call the justification void justifyTheText(string str, int L)
{ vector<string> words;
// Inserting words from
// given string
words = splitWords(str);
// Function call to
// justify the text
vector<string> result
= JustifyText(words, L);
// Print the justified
// text
printJustifiedText(result);
} // Driver Code int main()
{ string str
= "GeeksforGeeks is the best"
" computer science portal"
" for geeks." ;
int L = 16;
justifyTheText(str, L);
return 0;
} |
import java.util.ArrayList;
public class TextJustification {
// Function to join the words
// with spaces spread evenly
static String joinALineWithSpace(
ArrayList<String> 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
StringBuilder line = new StringBuilder();
for ( int i = start; i < end; i++) {
line.append(words.get(i));
--num_words_curr_line;
// Count number of current space needed
int num_curr_space
= ( int ) Math.ceil(( double ) (num_spaces)
/ num_words_curr_line);
// Insert spaces in string line
for ( int j = 0 ; j < num_curr_space; j++) {
line.append( ' ' );
}
// Delete the spaces inserted in line
num_spaces -= num_curr_space;
}
// Insert word to string line
line.append(words.get(end));
for ( int i = 0 ; i < num_spaces; i++) {
line.append( ' ' );
}
// Return justified text
return line.toString();
}
// Function that justifies the words of
// sentence of length of line L
static ArrayList<String> justifyText(
ArrayList<String> words,
int L) {
int curr_line_start = 0 ;
int num_words_curr_line = 0 ;
int curr_line_length = 0 ;
// To store the justified text
ArrayList<String> result = new ArrayList<>();
// Traversing the words array
for ( int i = 0 ; i < words.size(); i++) {
// currLineStart 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.get(i).length()
+ (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.add(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 that 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.add(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.get(i).length();
}
// If length is less than L then,
// add the word to current line length
else {
curr_line_length
+= words.get(i).length();
}
}
// Last line is to be left-aligned
if (num_words_curr_line > 0 ) {
StringBuilder line
= new StringBuilder(joinALineWithSpace(
words,
curr_line_start,
words.size() - 1 ,
num_words_curr_line - 1 ));
line.append(
" " .repeat(
L - curr_line_length
- (num_words_curr_line - 1 )));
// Insert the last line
// left-aligned to result
result.add(line.toString());
}
// Return result
return result;
}
// Function to insert words
// of sentence
static ArrayList<String> splitWords(String str) {
ArrayList<String> words = new ArrayList<>();
StringBuilder a = new StringBuilder();
for ( char c : str.toCharArray()) {
// Add char to string currentWord
// to get the word
if (c != ' ' ) {
a.append(c);
}
// If a space occurs
// split the words and
// add it to vector
else {
words.add(a.toString());
a = new StringBuilder();
}
}
// Push_back the last word
// of sentence
words.add(a.toString());
// Return the vector of
// words extracted from
// string
return words;
}
// Function to print justified text
static void printJustifiedText(ArrayList<String> result) {
for (String line : result) {
System.out.println(line);
}
}
// Function to call the justification
static void justifyTheText(String str, int L) {
ArrayList<String> words;
// Inserting words from
// given string
words = splitWords(str);
// Function call to
// justify the text
ArrayList<String> result
= justifyText(words, L);
// Print the justified
// text
printJustifiedText(result);
}
// Driver Code
public static void main(String[] args) {
String str
= "GeeksforGeeks is the best"
+ " computer science portal"
+ " for geeks." ;
int L = 16 ;
justifyTheText(str, L);
}
} // This Code is Contributed by Yash Agarwal(yashagarwal2852002) |
# Function to join the words # with spaces spread evenly def join_a_line_with_space(words, start, end, num_spaces):
# Number of words in the current line
num_words_curr_line = end - start + 1
# String to store the justified text
line = ""
for i in range (start, end):
line + = words[i]
num_words_curr_line - = 1
# Count the number of current space needed
num_curr_space = (num_spaces + num_words_curr_line - 1 ) / / num_words_curr_line
# Insert spaces in the string line
line + = " " * num_curr_space
# Delete the spaces inserted in the line
num_spaces - = num_curr_space
# Insert the last word to the string line
line + = words[end]
line + = " " * num_spaces
# Return justified text
return line
# Function that justifies the words of # a sentence of length of line L def justify_text(words, L):
curr_line_start = 0
num_words_curr_line = 0
curr_line_length = 0
# To store the justified text
result = []
# Traversing the words array
for i in range ( len (words)):
# curr_line_start is the first word
# in the current line, and i is
# used to identify the last word
num_words_curr_line + = 1
lookahead_line_length = curr_line_length + len (words[i]) + (num_words_curr_line - 1 )
# If by including the words, the 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
ans = join_a_line_with_space(words, curr_line_start, i, i - curr_line_start)
# Store the justified text in the result
result.append(ans)
# Start the current line
# with the 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 that set is justified with
# one less word and add the
# justified text to result
elif lookahead_line_length > L:
# Justify the set of words
ans = join_a_line_with_space(words, curr_line_start, i - 1 , L - curr_line_length)
# Store the justified text in the result
result.append(ans)
# Current line set to the current word
curr_line_start = i
# Number of words set to 1
num_words_curr_line = 1
# Current line length set
# to the current word length
curr_line_length = len (words[i])
# If length is less than L then,
# add the word to current line length
else :
curr_line_length + = len (words[i])
# Last line is to be left-aligned
if num_words_curr_line > 0 :
line = join_a_line_with_space(words, curr_line_start, len (words) - 1 , num_words_curr_line - 1 )
line + = " " * (L - curr_line_length - (num_words_curr_line - 1 ))
# Insert the last line
# left-aligned to result
result.append(line)
# Return result
return result
# Function to insert words # of a sentence def split_words(s):
words = s.split()
return words
# Function to print justified text def print_justified_text(result):
for line in result:
print (line)
# Function to call the justification def justify_the_text(s, L):
# Inserting words from
# the given string
words = split_words(s)
# Function call to
# justify the text
result = justify_text(words, L)
# Print the justified
# text
print_justified_text(result)
# Driver Code if __name__ = = "__main__" :
s = "GeeksforGeeks is the best computer science portal for geeks."
L = 16
justify_the_text(s, L)
|
using System;
using System.Collections.Generic;
using System.Text;
public class TextJustification
{ // Function to join the words
// with spaces spread evenly
static string JoinALineWithSpace(List< string > 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
StringBuilder line = new StringBuilder();
for ( int i = start; i < end; i++)
{
line.Append(words[i]);
--num_words_curr_line;
// Count number of current space needed
int num_curr_space = ( int )Math.Ceiling(( double )(num_spaces) / num_words_curr_line);
// Insert spaces in string line
for ( int j = 0; j < num_curr_space; j++)
{
line.Append( ' ' );
}
// Delete the spaces inserted in line
num_spaces -= num_curr_space;
}
// Insert word to string line
line.Append(words[end]);
for ( int i = 0; i < num_spaces; i++)
{
line.Append( ' ' );
}
// Return justified text
return line.ToString();
}
// Function that justifies the words of
// sentence of length of line L
static List< string > JustifyText(List< string > words, int L)
{
int curr_line_start = 0;
int num_words_curr_line = 0;
int curr_line_length = 0;
// To store the justified text
List< string > result = new List< string >();
// Traversing the words array
for ( int i = 0; i < words.Count; i++)
{
// currLineStart 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].Length + (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.Add(ans);
// Start the current line
// with the 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 that 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.Add(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].Length;
}
// If length is less than L then,
// add the word to current line length
else
{
curr_line_length += words[i].Length;
}
}
// Last line is to be left-aligned
if (num_words_curr_line > 0)
{
StringBuilder line =
new StringBuilder(JoinALineWithSpace(words, curr_line_start,
words.Count - 1, num_words_curr_line - 1));
line.Append( " " .PadRight(L - curr_line_length - (num_words_curr_line - 1)));
// Insert the last line
// left-aligned to result
result.Add(line.ToString());
}
// Return result
return result;
}
// Function to insert words
// of sentence
static List< string > splitWords( string str)
{
List< string > words = new List< string >();
StringBuilder currentWord = new StringBuilder();
foreach ( char c in str)
{
// Add char to string currentWord
// to get the word
if (c != ' ' )
{
currentWord.Append(c);
}
// If a space occurs
// split the words and
// add it to vector
else
{
words.Add(currentWord.ToString());
currentWord = new StringBuilder();
}
}
// Add the last word of the sentence
words.Add(currentWord.ToString());
// Return the list of
// words extracted from
// string
return words;
}
// Function to print justified text
static void printJustifiedText(List< string > result)
{
foreach ( string line in result)
{
Console.WriteLine(line);
}
}
// Function to call the justification
static void justifyTheText( string str, int L)
{
List< string > words;
// Inserting words from
// given string
words = splitWords(str);
// Function call to
// justify the text
List< string > result = JustifyText(words, L);
// Print the justified
// text
printJustifiedText(result);
}
// Driver Code
public static void Main( string [] args)
{
string str = "GeeksforGeeks is the best computer science portal for geeks." ;
int L = 16;
justifyTheText(str, L);
}
} // This code is contributed by Yash Agarwal(yashagarwal2852002) |
// Function to join the words // with spaces spread evenly function JoinALineWithSpace(words, start, end, num_spaces) {
// Number of words in the current line
let num_words_curr_line = end - start + 1;
// String to store the justified text
let line = '' ;
for (let i = start; i < end; i++) {
line += words[i];
num_words_curr_line--;
// Count number of current space needed
let num_curr_space = Math.ceil(num_spaces / num_words_curr_line);
// Insert spaces in string line
line += ' ' .repeat(num_curr_space);
// Delete the spaces inserted in line
num_spaces -= num_curr_space;
}
// Insert word to string line
line += words[end];
line += ' ' .repeat(num_spaces);
// Return justified text
return line;
} // Function that justifies the words of // sentence of length of line L function JustifyText(words, L) {
let curr_line_start = 0;
let num_words_curr_line = 0;
let curr_line_length = 0;
// To store the justified text
const result = [];
// Traversing the words array
for (let i = 0; i < words.length; i++) {
num_words_curr_line++;
const lookahead_line_length = curr_line_length + words[i].length + (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) {
const ans = JoinALineWithSpace(words, curr_line_start, i, i - curr_line_start);
result.push(ans);
// Start the current line with the next index
curr_line_start = i + 1;
num_words_curr_line = 0;
curr_line_length = 0;
}
// If by including the words such that
// length of words becomes greater than L,
// then that set is justified with
// one less word and add the
// justified text to result
else if (lookahead_line_length > L) {
const ans = JoinALineWithSpace(words, curr_line_start, i - 1, L - curr_line_length);
result.push(ans);
// Current line set to current word
curr_line_start = i;
num_words_curr_line = 1;
curr_line_length = words[i].length;
}
// If length is less than L then,
// add the word to current line length
else {
curr_line_length += words[i].length;
}
}
// Last line is to be left-aligned
if (num_words_curr_line > 0) {
let line = JoinALineWithSpace(words, curr_line_start, words.length - 1, num_words_curr_line - 1);
line += ' ' .repeat(L - curr_line_length - (num_words_curr_line - 1));
// Insert the last line left-aligned to result
result.push(line);
}
// Return result
return result;
} // Function to insert words // of sentence function splitWords(str) {
const words = [];
let a = '' ;
for (let 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(a);
a = '' ;
}
}
// Push back the last word
// of sentence
words.push(a);
// Return the vector of
// words extracted from
// string
return words;
} // Function to print justified text function printJustifiedText(result) {
for (const it of result) {
console.log(it);
}
} // Function to call the justification function justifyTheText(str, L) {
let words;
// Inserting words from
// given string
words = splitWords(str);
// Function call to
// justify the text
const result = JustifyText(words, L);
// Print the justified
// text
printJustifiedText(result);
} // Driver Code const str = "GeeksforGeeks is the best computer science portal for geeks." ;
const L = 16; justifyTheText(str, L); |
GeeksforGeeks is the best computer science portal for geeks.
Time Complexity: O(N), where N = length of string