SWE · Coding

Google Doc行数:换行、空白、长词与字符宽度

给文本和最大宽度,先明确排版是否保留空格及是否按词换行。

题目重点:给文本和最大宽度,先明确排版是否保留空格及是否按词换行。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版等宽、每字符一列,保留全部空格, 显式换行;超过width硬折行,不采用单词重排。
  • 空字符串一行,末尾 产生最后空行。Unicode宽字、tab、CRLF与真实字体未纳入,不能称真实Doc排版。

解题路线

  1. split按 保留尾部空段,每段len为L,需要max(1,ceil(L/width))行;空段也代表显式空行。
  2. 逐字符状态机可独立核验:列满后仅在下一个普通字符到来时新增折行,遇 直接新增行并重置列。因此恰好width后跟 不应额外生成折行。
  3. 按词换行则要维护词长度和行剩余宽度,定义多空格折叠、长词拆分、连字符。比例字体需要测量glyph advance/换行机会,简单字符数无法替代。

手动走一遍

width3,abc def为2行,不是3行;abc 末尾空行使2行。四个空格width3需2行,不能strip后认为只1行。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def line_count(text,width):
    # Each char occupies one column; spaces retained; newline starts a new line.
    # Long runs hard-wrap. A trailing newline creates an empty final line.
    if width<=0:raise ValueError("positive width required")
    return sum(max(1,(len(line)+width-1)//width) for line in text.split("\n"))

复杂度

O(L)时间/O(L)split辅助空间;逐字符实现可O(1)辅助,L文本字符数。

易错点与追问

容易失分的边界

  • split()无参数会丢空格和显式空行。
  • 把ceil(0/width)=0直接相加会漏空段。

继续深挖

  • 按词换行时输入a空格空格b应保留还是折叠?
  • tab按当前列跳tab stop,为何不能固定算一个字符宽?
✓已复制微信号!