# 文本左右对齐

给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。

你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。

要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。

文本的最后一行应为左对齐,且单词之间不插入额外的空格。

说明:

示例:

输入:
    words = ["This", "is", "an", "example", "of", "text", "justification."]
    maxWidth = 16
输出:
    [
       "This    is    an",
       "example  of text",
       "justification.  "
    ]
    

示例 2:

输入:
    words = ["What","must","be","acknowledgment","shall","be"]
    maxWidth = 16
输出:
    [
      "What   must   be",
      "acknowledgment  ",
      "shall be        "
    ]
解释: 注意最后一行的格式应为 "shall be    " 而不是 "shall     be"
    因为最后一行应为左对齐,而不是左右两端对齐,第二行同样为左对齐,这是因为这行只包含一个单词。
    

示例 3:

输入:
    words = ["Science","is","what","we","understand","well","enough","to","explain",
             "to","a","computer.","Art","is","everything","else","we","do"]
    maxWidth = 20
输出:
    [
      "Science  is  what we",
      "understand      well",
      "enough to explain to",
      "a  computer.  Art is",
      "everything  else  we",
      "do                  "
    ]
    
以下程序实现了这一功能,请你填补空白处的内容: ```cpp #include #include #include static void line_fill(char *line, int len, char **words, int *word_lens, int max_size, int even_spaces, int remain_spaces, int start, int end) { int i, j; char *p = line; for (i = start; i < end; i++) { memcpy(p, words[i], word_lens[i]); p += word_lens[i]; if (i < end - 1) { ___________________; } } while (p - line < max_size) { *p++ = ' '; } *p++ = '\0'; } static char **fullJustify(char **words, int wordsSize, int maxWidth, int *returnSize) { int i, j, k, cap = 100, count = 0; char **lines = malloc(cap * sizeof(char *)); char *buf = malloc(cap * (maxWidth + 1)); for (i = 0; i < cap; i++) { lines[i] = buf + i * (maxWidth + 1); } int *word_lens = malloc(wordsSize * sizeof(int)); for (i = 0; i < wordsSize; i++) { word_lens[i] = strlen(words[i]); } int wc = 0; int len = 0; int start = 0; int chars = 0; for (i = 0, j = 0; i < wordsSize; i++) { if (len + word_lens[i] > maxWidth) { int even_spaces = wc == 1 ? 0 : (maxWidth - chars) / (wc - 1); int remain_spaces = wc == 1 ? 0 : (maxWidth - chars) % (wc - 1); line_fill(lines[count], len, words, word_lens, maxWidth, even_spaces, remain_spaces, start, i); count++; wc = 1; len = word_lens[i] + 1; chars = word_lens[i]; start = i; } else if (len + word_lens[i] == maxWidth) { chars += word_lens[i]; int even_spaces = wc == 0 ? 0 : (maxWidth - chars) / wc; int remain_spaces = wc == 0 ? 0 : (maxWidth - chars) % wc; line_fill(lines[count], len, words, word_lens, maxWidth, even_spaces, remain_spaces, start, i + 1); count++; wc = 0; len = 0; chars = 0; start = i + 1; } else { chars += word_lens[i]; len += word_lens[i] + 1; wc++; } } if (wc > 0) { char *p = lines[count]; for (i = start; i < start + wc; i++) { memcpy(p, words[i], word_lens[i]); p += word_lens[i]; if (i < start + wc - 1) { *p++ = ' '; } } while (p - lines[count] < maxWidth) { *p++ = ' '; } *p++ = '\0'; count++; } *returnSize = count; return lines; } int main(int argc, char **argv) { if (argc <= 2) { fprintf(stderr, "Usage: ./test maxsize words...\n"); exit(-1); } int i, count; char **lines = fullJustify(argv + 2, argc - 2, atoi(argv[1]), &count); for (i = 0; i < count; i++) { printf("%s\n", lines[i]); } return 0; } ``` ## template ```cpp #include #include #include static void line_fill(char *line, int len, char **words, int *word_lens, int max_size, int even_spaces, int remain_spaces, int start, int end) { int i, j; char *p = line; for (i = start; i < end; i++) { memcpy(p, words[i], word_lens[i]); p += word_lens[i]; if (i < end - 1) { for (j = 0; j < even_spaces; j++) { *p++ = ' '; } if (remain_spaces > 0) { *p++ = ' '; remain_spaces--; } } } while (p - line < max_size) { *p++ = ' '; } *p++ = '\0'; } static char **fullJustify(char **words, int wordsSize, int maxWidth, int *returnSize) { int i, j, k, cap = 100, count = 0; char **lines = malloc(cap * sizeof(char *)); char *buf = malloc(cap * (maxWidth + 1)); for (i = 0; i < cap; i++) { lines[i] = buf + i * (maxWidth + 1); } int *word_lens = malloc(wordsSize * sizeof(int)); for (i = 0; i < wordsSize; i++) { word_lens[i] = strlen(words[i]); } int wc = 0; int len = 0; int start = 0; int chars = 0; for (i = 0, j = 0; i < wordsSize; i++) { if (len + word_lens[i] > maxWidth) { int even_spaces = wc == 1 ? 0 : (maxWidth - chars) / (wc - 1); int remain_spaces = wc == 1 ? 0 : (maxWidth - chars) % (wc - 1); line_fill(lines[count], len, words, word_lens, maxWidth, even_spaces, remain_spaces, start, i); count++; wc = 1; len = word_lens[i] + 1; chars = word_lens[i]; start = i; } else if (len + word_lens[i] == maxWidth) { chars += word_lens[i]; int even_spaces = wc == 0 ? 0 : (maxWidth - chars) / wc; int remain_spaces = wc == 0 ? 0 : (maxWidth - chars) % wc; line_fill(lines[count], len, words, word_lens, maxWidth, even_spaces, remain_spaces, start, i + 1); count++; wc = 0; len = 0; chars = 0; start = i + 1; } else { chars += word_lens[i]; len += word_lens[i] + 1; wc++; } } if (wc > 0) { char *p = lines[count]; for (i = start; i < start + wc; i++) { memcpy(p, words[i], word_lens[i]); p += word_lens[i]; if (i < start + wc - 1) { *p++ = ' '; } } while (p - lines[count] < maxWidth) { *p++ = ' '; } *p++ = '\0'; count++; } *returnSize = count; return lines; } int main(int argc, char **argv) { if (argc <= 2) { fprintf(stderr, "Usage: ./test maxsize words...\n"); exit(-1); } int i, count; char **lines = fullJustify(argv + 2, argc - 2, atoi(argv[1]), &count); for (i = 0; i < count; i++) { printf("%s\n", lines[i]); } return 0; } ``` ## 答案 ```cpp for (j = 0; j < even_spaces; j++) { *p++ = ' '; } if (remain_spaces > 0) { *p++ = ' '; remain_spaces--; } ``` ## 选项 ### A ```cpp for (j = 0; j < even_spaces; j++) { *p++ = ' '; } if (remain_spaces > 0) { *p++ = ' '; remain_spaces++; } ``` ### B ```cpp for (j = 0; j < even_spaces; j++) { *p++ = ' '; } if (remain_spaces < 0) { *p++ = ' '; remain_spaces++; } ``` ### C ```cpp for (j = 0; j < even_spaces; j++) { *p++ = '\0'; } if (remain_spaces > 0) { *p++ = '\0'; remain_spaces--; } ```