
题目考点
这道题主要考:
字符串处理、标准库 textwrap 的使用、函数返回值、换行符 \n、字符串拼接。
这题不是让我们判断字符大小,也不是比较 ASCII 码,而是把一个长字符串按照固定宽度切成多行。
审题
题目给我们两个数据:
string:一个长字符串
max_width:每一行最多放多少个字符
要求我们做的事情是:
把 string 每隔 max_width 个字符换一行,最后返回一个新的字符串。
例如输入:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
4
意思是:每一行最多 4 个字符。
所以应该切成:
ABCD
EFGH
IJKL
MNOP
QRST
UVWX
YZ
注意最后一行不一定刚好是 4 个字符。比如最后只剩下 YZ,也要单独作为一行。
思路提示
先不要急着写代码。你可以这样想:
原字符串是一整条:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
宽度是 4,那么我们要做的是:
从第 0 个字符开始,取 4 个字符
从第 4 个字符开始,再取 4 个字符
从第 8 个字符开始,再取 4 个字符
……
也就是:
string[0:4]
string[4:8]
string[8:12]
string[12:16]
...
然后把这些小段用换行符 \n 连接起来。
不过这道 HackerRank 题通常希望我们使用 Python 的 textwrap 模块,所以可以更简单地完成。
完整设计思路
第一步:使用 textwrap.wrap()
Python 有一个标准库叫 textwrap,专门用于处理“文本换行”。
它里面的 wrap() 函数可以把一个字符串按照指定宽度切成一个列表。
例如:
import textwrap
result = textwrap.wrap("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4)
print(result)
结果是:
['ABCD', 'EFGH', 'IJKL', 'MNOP', 'QRST', 'UVWX', 'YZ']
注意,它返回的是一个列表,不是最终要输出的字符串。
第二步:把列表用换行符连接起来
题目要求返回的是一个带有换行符 \n 的字符串。
所以我们需要用:
"\n".join(result)
把列表变成:
ABCD
EFGH
IJKL
MNOP
QRST
UVWX
YZ
代码实现
这道题最推荐的写法是:
import textwrap
def wrap(string, max_width):
lines = textwrap.wrap(string, max_width)
return "\n".join(lines)
if __name__ == '__main__':
string = input()
max_width = int(input())
result = wrap(string, max_width)
print(result)
也可以更简洁地写成:
import textwrap
def wrap(string, max_width):
return "\n".join(textwrap.wrap(string, max_width))
if __name__ == '__main__':
string = input()
max_width = int(input())
result = wrap(string, max_width)
print(result)
代码解释
这一句:
import textwrap
表示引入 Python 自带的文本处理工具。它是标准库,不需要额外安装。
这一句:
textwrap.wrap(string, max_width)
会把字符串按照 max_width 的宽度切成很多小字符串,结果是一个列表。
比如:
textwrap.wrap("ABCDEFGHIJ", 4)
结果是:
['ABCD', 'EFGH', 'IJ']
这一句:
"\n".join(lines)
表示把列表里的每一段用换行符连接起来。
例如:
lines = ['ABCD', 'EFGH', 'IJ']
执行:
"\n".join(lines)
结果就是:
ABCD
EFGH
IJ
运行演示
输入:
ABCDEFGHIJKL
4
程序先读取:
string = "ABCDEFGHIJKL"
max_width = 4
然后执行:
textwrap.wrap(string, max_width)
得到:
['ABCD', 'EFGH', 'IJKL']
再执行:
"\n".join(['ABCD', 'EFGH', 'IJKL'])
得到:
ABCD
EFGH
IJKL
最后 print(result) 打印出来:
ABCD
EFGH
IJKL
不用 textwrap 的手写思路
如果不用标准库,也可以用字符串切片自己做:
def wrap(string, max_width):
lines = []
for i in range(0, len(string), max_width):
part = string[i:i + max_width]
lines.append(part)
return "\n".join(lines)
这里的核心是:
range(0, len(string), max_width)
意思是从 0 开始,每次跳 max_width 个位置。
例如 max_width = 4,那么 i 会依次是:
0, 4, 8, 12, 16 ...
于是就可以切:
string[0:4]
string[4:8]
string[8:12]
这就是手动实现换行的本质。
方法总结
这类题的识别方法是:
看到“把字符串按固定长度分组”“每隔几个字符换行”“wrap string”“width”这些词,就要想到两种做法:
第一种,用 Python 标准库:
textwrap.wrap()
第二种,自己用字符串切片:
string[i:i + width]
如果题目来自 HackerRank 的 Text Wrap,优先使用 textwrap,因为这就是它想考的工具。
小练习
请你自己尝试写一个函数:
给定字符串:
hellopython
宽度:
3
要求输出:
hel
lop
yth
on
提示:可以使用 textwrap.wrap(),也可以用 for i in range(0, len(string), width) 自己切片。
所以这道题目最关键的就是切片之后,通过”\n”.join(textwrap.wrap(string, max_width))这个进行合并,数据结构是通过字符串到列表,再用换行符连接起来,成为字符串
对,你这个理解是正确的。这道题的核心数据变化就是:
原始字符串 string
↓ textwrap.wrap(string, max_width)
列表 list
↓ "\n".join(...)
带换行符的字符串
具体来说,假设:
string = "ABCDEFGHIJ"
max_width = 4
第一步:
textwrap.wrap(string, max_width)
得到的是列表:
['ABCD', 'EFGH', 'IJ']
注意:这里还没有真正“显示成多行”,它只是把字符串切成了多个小字符串,放进列表里。
第二步:
"\n".join(['ABCD', 'EFGH', 'IJ'])
得到的是一个新的字符串:
"ABCD\nEFGH\nIJ"
这个字符串内部包含换行符 \n。当你用 print() 打印它时,才会显示成:
ABCD
EFGH
IJ
所以这道题最关键的是两件事:
第一,textwrap.wrap(string, max_width) 负责“切”,把长字符串切成列表。
第二,"\n".join(...) 负责“合并”,把列表重新合成一个字符串,并且每两个小段之间插入一个换行符。
也可以这样理解:
return "\n".join(textwrap.wrap(string, max_width))
等价于:
parts = textwrap.wrap(string, max_width)
result = "\n".join(parts)
return result
对于初学者,后面这种分两步写更容易看懂。等熟悉以后,再写成一行。



