How to justify and print a paragraph using a 2d array in C?

Solution 1:

Consider how many spaces you have to distribute. For example, given the input:

18
I am the very model of a modern Major-General.

Computing the number of words that fit on the line goes:

"I" + "am" + "the" + "very"           + (4-1 words) --> 13
"I" + "am" + "the" + "very" + "model" + (5-1 words) --> 19

So only the first 4 words fit on an 18-character line. The number of space characters to distribute are then easily calculated:

N = max_line_width - sum_of_word_lengths

Now for the hard part: how many spaces between each word? Your homework expects you to divvy extra unbalanced spaces left-to-right, meaning that each pair of words may have a different number of space characters.

However, the difference will always be a single space character. Take a moment to convince yourself this is true:

I···am···the··very
-2-4-6-8-0-2-4-6-8

In our little example, we find that there are three space characters in the first two inter-word spacings, and two space characters in the last.

The minimum number of space characters per inter-word spacing is easy enough to caluclate:

nsp = N / (number_of_words_in_line - 1)

Beware! What happens if you have only one word on the line? (Do you really need to distribute spaces for such a line?)

And now, for the cool tricky math part, you can calculate the number of times you need to add a space to the inter-word spacing as:

nplus1 = N - nsp * (number_of_words_in_line - 1)

or just:

nplus1 = N % (number_of_words_in_line - 1)

Keep in mind that it is possible that all inter-word spacings are the same number of space characters, and may be exactly one space character even. Notice how our calculations work just as well in those cases.

Now you can print the words for the line in a loop, adding nsp space characters after every word, plus an extra space after the first nplus1 words.

Remember, the last word of the line doesn’t get any spaces. It is followed by a newline!

Hopefully this should help you work your way through this assignment. (I personally think it is a bit of a careless assignment as your first ever, introduction to C class.)

And now, if I have made errors, it is because I am very, very sleepy. Someone will surely point it out if I have.

Solution 2:

So using Dúthomhas' suggestion I was able to create the function below:

void justifyAndPrintLine(char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH], int processedWords, int amountOfWordsForNextLine, int lineLength) {
    int total = 0;
    for (int i = processedWords; i < processedWords + amountOfWordsForNextLine; i++) {
        total += (int) strlen(words[i]);
    }
    int spaces = lineLength - total;
    int spacesBetweenWords = spaces / (amountOfWordsForNextLine - 1);
    int spacesRemaining = spaces % (amountOfWordsForNextLine - 1);
    int spaceForThisWord;
    int leftWords = processedWords + amountOfWordsForNextLine;
    while (processedWords != leftWords) {
        spaceForThisWord = spacesBetweenWords;
        if (spacesRemaining > 0) {
            spaceForThisWord++;
            spacesRemaining--;
        }
        printLine(words[processedWords], spaceForThisWord);
        processedWords++;
    }
}

A key part of my understanding of the math was that the difference in spacing was always going to a single space character. Borrowing his math I was able to properly justify the paragraph. Thanks again Dúthomhas!