如何在 C 中使用二维数组证明和打印段落?

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

我的作业基本上是要求在给定行长的情况下证明段落的合理性。例如段落 “我是C班的学生,这是我的第一份作业,希望能按时完成。”给定的行长度 17 应如下所示:

output
I am a student of
C,   this  is  my 
first assignment.
I  hope  I finish
on          time. 

我在动态放置单词之间的间距时遇到了问题。我目前有一个函数可以计算段落中的单词并将它们存储到二维数组中,但我不知道如何 a) 计算单词之间的间距量和 b) 如何动态打印对齐的段落。 这是我到目前为止的代码:


int getAllWordsFrom2DArray(char *paragraph, char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH]) {
    int i,j,totalWords = 0;
    for(i=0; i < strlen(paragraph); i++) {
        int wordLength;
        if (paragraph[i] == ' ' || paragraph[i+1] == '[=11=]') {
            totalWords++;
            wordLength = i;
            for(j=0; j < wordLength; j++) {
                words[i][j] = paragraph[j];
            }
        }
    }
    printf("%s", words);

    return totalWords;
}


//Code in progress
int getNumberOfWordsForNextLine(int totalWords, int lineLength, char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH]) {
    int wordsForNextLine = 0;
    for(int i=0; i < totalWords; i++) {
        wordsForNextLine = 0 ;
    }
}

//code in progress
void printNextLine(int wordsForNextLine) {

}


//skeleton code provided by instructor
void justifyAndPrintParagraph(char* paragraph, int lineLength) {
    char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH];
    int totalWords = getAllWordsFrom2DArray(paragraph, words);
    int processedWords = 0;

    while (processedWords < totalWords) {
        int wordsForNextLine = getNumberOfWordsForNextLine(totalWords, lineLength, words);
        printNextLine(wordsForNextLine);
        processedWords += wordsForNextLine;
    }
}

澄清一下,我们不允许使用 strlok。本质上,我们应该只使用基础知识来做这件事。我需要使用 void justifyAndPrintParagraph 函数和签名,但除此之外我可以自由地做任何事情。

编辑:我忘了补充一点,如果空间不能平均分配,那么多余的空间将从左到右分配。

非常感谢任何帮助。

考虑您必须分发多少 space。例如,给定输入:

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

计算适合该行的字数:

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

所以只有前 4 个单词适合 18 个字符的行。然后很容易计算出要分配的 space 个字符数:

N = max_line_width - sum_of_word_lengths

现在是困难的部分:每个单词之间有多少 space?你的作业要求你分配额外的不平衡 spaces left-to-right,这意味着每对单词可能有 不同 个 space 个字符。

但是,区别将始终是 单个 space 个字符。花点时间让自己相信这是真的:

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

在我们的小例子中,我们发现前两个inter-word间距有三个space个字符,两个 最后 space 个字符。

每个 inter-word 间距的 最小 个 space 个字符很容易计算:

nsp = N / (number_of_words_in_line - 1)

小心!如果线上只有 一个 字会怎样? (这么一行真的需要分发space吗?)

现在,对于很酷的棘手数学部分,您可以计算需要将 space 添加到 inter-word 间距的次数:

nplus1 = N - nsp * (number_of_words_in_line - 1)

或者只是:

nplus1 = N % (number_of_words_in_line - 1)

请记住,所有 inter-word 间距可能都是相同数量的 space 个字符,并且可能恰好是 一个 space 字偶。请注意我们的计算在这些情况下是如何工作的。

现在您可以循环打印该行的单词,在每个单词后添加 nsp space 个字符,并在第一个 nplus1 后添加一个额外的 space单词。

请记住,该行的 last 字没有任何 space。后面跟一个换行符!

希望这能帮助您完成这项作业。 (我个人认为,作为您第一次接触 C class,这是一项粗心的作业。)

现在,如果我犯了错误,那是因为我非常非常困。有的话肯定会有人指出来的。

因此,根据 Dúthomhas 的建议,我能够创建以下函数:

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++;
    }
}

我对数学的理解的一个关键部分是间距的差异总是指向单个 space 字符。借用他的数学,我能够恰当地证明该段落的合理性。再次感谢 Dúthomhas!