📅  最后修改于: 2023-12-03 15:25:46.513000             🧑  作者: Mango
在字符串相关问题中,经常需要求解最长前缀和后缀。本文主要介绍如何打印给定字符串的最长前缀,同时也是同一字符串的后缀。
在了解如何打印最长前缀后缀之前,先来了解一下最长前缀和后缀的定义。
对于一个字符串 $S$,假设存在一个非空的前缀 $s$,使得 $s$ 既是 $S$ 的前缀,又是 $S$ 的后缀。那么 $s$ 就是 $S$ 的最长前缀后缀。
比如字符串 $S="ababab"$,它的最长前缀后缀为 $s="ab"$,因为 $S$ 的前缀 $s_1="a"$, $s_2="ab"$, $s_3="aba"$,$s_4="abab"$, $s_5="ababa"$,都不是 $S$ 的后缀;而 $s="ab"$ 同时是 $S$ 的前缀和后缀。
我们可以使用 KMP 算法求解字符串的最长前缀后缀。不过在这里,我们介绍一种更加直观简单的方法。
假设字符串 $S$ 的长度为 $n$。我们先把字符串 $S$ 按照长度从 $1$ 到 $n$ 分别截取成若干个前缀和后缀,然后从后往前遍历,找到第一个既是前缀又是后缀的子串即可。
具体操作如下:
对于字符串 $S$,截取长度为 $i(i=1,2,...,n)$ 的前缀 $p$ 和后缀 $s$。
从 $p$ 的末尾和 $s$ 的开始匹配,如果匹配到了,则证明存在子串 $ss$ 既是 $p$ 的前缀又是 $s$ 的后缀。
当前的 $ss$ 就是字符串 $S$ 的最长前缀后缀,输出即可。
下面是 Python 代码:
def longest_prefix_suffix(s):
n = len(s)
for i in range(n - 1, -1, -1):
p = s[:i]
sfix_s = s[n - i:]
j = 0
while j < len(p) and p[j:] == sfix_s[:len(p) - j]:
j += 1
if j > 0:
return s[:j]
return ""
在这个算法中,我们从后往前遍历,因此时间复杂度为 $O(n^2)$。
本文介绍了如何打印给定字符串的最长前缀,同时也是同一字符串的后缀。我们的做法比较简单,虽然时间复杂度不够优秀,但是对于字符串较短的情况,完全可以满足需求。
另外,如果在实际问题中遇到字符串相关问题,建议优先考虑 KMP 算法。