Greedy Text Justification
March 30, 2021
Our solution is in two parts. The outer part deals with selecting the words to appear on the line, the inner part deals with justification. Here’s the outer part:
(define (justify str line-width) (let loop ((words (string-split #\space str)) (line (list)) (curr-width 0)) (cond ((null? words) (when (pair? line) (write-line line (+ (length line) -1 (sum (map string-length line)))))) ((< line-width (+ curr-width (string-length (car words)))) (write-line line line-width) (loop words (list) 0)) (else (loop (cdr words) (cons (car words) line) (+ curr-width (string-length (car words)) 1))))))
We are assuming that all words are shorter than line-width
.
Function write-line
first handles the first word on the line (there must always be one) followed by a loop that writes each succeeding word along with its separator prefix and extra space if needed:
(define (write-line rev-words width) (let* ((words (reverse rev-words)) (first-word (car words)) (width (- width (string-length first-word))) (words (cdr words))) (display first-word) (if (null? words) (newline) (let* ((nblanks (- width (sum (map string-length words)))) (sep (make-string (quotient nblanks (length words)) #\space)) (nextra (remainder nblanks (length words)))) (do ((n 0 (+ n 1)) (words words (cdr words))) ((null? words) (newline)) (display sep) (when (< n nextra) (display #\space)) (display (car words)))))))
You can run the program at https://ideone.com/NFKI0N.
Here is a solution in standard R7RS Scheme plus a few well-known
helpers. It focuses more on clarity than on low-level efficiency.
#include<graphics.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>
void main()
{
char* str;
int x=0,y,i,l,j,e=34,gd=DETECT,gm;
clrscr();
initgraph(&gd,&gm,”c:\turboc3\bgi”);
setbkcolor(GREEN);
printf(“Enter the data:\n”);
gets(str);
l=strlen(str);
if(l<e)
puts(str);
else
{
for(i=0;i<(l/e);i++)
{
for(j=0;j<e;j++)
{
printf(“%c”,str[x]);
x++;
}
printf(“\n”);
}
y=l%e;
while(y)
{ printf(“%c”,str[x]);
x++;
y–;
}
}
getch();
closegraph();
}
A solution in Racket:
Examples:
Here’s a solution in Python.
Output:
Out:
// This is not the exact answeer. it is written in c++ your comments please to improve it so that output matches
#include
#include
using namespace std;
int main()
{
int i = 0;
int del = 0;
int del2;
string delim = ” “;
int strlength;
int linewidth = 16;
string s;
s = “This is a justified text below”;
string* sub = new string[s.length()];
while (true)
{
del2 = s.find(delim, del);
//cout << del2 << endl;
//cout << del << endl;
if (del2 == -1) {
sub[i] = s.substr(del, s.length());
break;
}
else
{
sub[i] = new char[s.substr(del, del2).length() + 1];
sub[i] = s.substr(del, del2 – del);
del = del2 + delim.length();
//cout <<sub[i] << endl;
i++;
}
}
cout << i << endl;
i = i+1 ;
int j;
int lengths = 0;
int k = 0;
int m=0;
for (int y = 0; y < 5; y++)
{
lengths = 0;
}
Here’s a Haskell version.