|
基本是多余的!
在已满足 n % i == 0 的前提下,设候选模式 p = s[i:i*2],如果 s.count(p) == n//i,说明在长度为 n 的字符串里,有 恰好 n//i 个互不重叠、长度为 i 的 p。这些片段总长度是 i * (n//i) = n,因此它们必须把整串从头到尾“铺满”。
要想铺满且不越界,最左边那个必然从下标 0 开始,后面只能出现在 i, 2i, 3i, …。
所以这时自然有 s.startswith(p),也就是 s[:i] == s[i:i*2]。
因此 startswith 判断在这个逻辑下确实是冗余的。
一些小建议(优化代码)
用整数除法更合适:n//i(/ 在Python3里是浮点除法)。
直接用开头那段作为模式更直观,也避免读者困惑:p = s[:i]。
这样写既清晰也等价,且无须 count 的微妙语义:
- s = input("请输入一个由字母构成的字符串:")
- n = len(s)
- for i in range(1, n // 2 + 1):
- if n % i == 0:
- p = s[:i]
- if p * (n // i) == s:
- print(True)
- break
- else:
- print(False)
复制代码
再送两个常见的一行/线性时间写法(了解即可):
- 经典拼接技巧:print(s in (s + s)[1:-1])(判断是否由某个子串重复且至少两次)。
- KMP前缀函数法(O(n)):求 lps,若 n % (n - lps[-1]) == 0 且 lps[-1] > 0 则为真。
|
|