在英文字处理程序中,由于单词都是由字母序列构成,所以当输入到一行的末尾的时候,就会遇到想要输入的单词长度大于所剩余的空白长度的情况,这就是折行问题。对于手写文本,我们可以用连字符‘-’把单词分割到两行上,但是对于字处理程序而言,其拥有更强的处理能力,可以通过运算来避免单词被分割到两行上。
目前对于文本的折行,比较流行的是贪心算法,也就是尝试在当前行中放下尽可能多的单词,当前行不能再容纳更多单词时,就放到下一行。这样进行折行,对于输入的段落,其折行后的结果,行数最少。对于行宽为6,输入文本"aaa bb cc ddddd",使用贪心算法生成的折行后结果为:
------
aaa bb
cc
ddddd
在第二行的输入中,发现输入单词'cc'之后,后面只有3个空位(单词之间有一个空格作为分隔符),而下一个单词'ddddd'的长度为5,所以只能将'ddddd'输出到第3行,对于行宽比较小的情况下,贪心算法会造成个别行右侧的空白较大,显得不是很协调。但是对于常用的字处理程序来说,行宽一般为几十,且这些程序在执行折行的同时还会动态调整行内各单词的间距,所以美观问题不是很大。
要实现折行算法,首先需要把输入的字符串分割成一系列单词,GetWords()函数负责实现此功能,将文本中的单词逐个分离出来,添加到单词数组中。该函数实现的功能比较简单,他将空白视为单词的分隔符,如果两个单词之间包含多个空白符号,函数会将其忽略。
void GetWords(const string& text, vector<string>& words_array)
{
string::const_iterator word_begin, word_end;
word_begin = word_end = text.begin();
while (word_begin != text.end())
{
if (!isgraph(*word_begin))
{
++word_begin;
++word_end;
continue;
}
if (isgraph(*word_end))
{
++word_end;
}
else
{
words_array.push_back(string(word_begin, word_end));
word_begin = word_end;
}
}
}
贪心折行算法以原始文本作为输入,通过GetWords()函数将文本分割为一系列单词,再利用贪心