简单题:串的前缀

文章介绍了一种字符串处理问题,要求找到给定字符串中每个前缀的最长真前缀,使得剩余部分是这个真前缀的前缀。提供了两种解题思路,一种是暴力循环模拟,另一种是基于前缀函数的优化方法。代码示例使用Python实现,主要涉及字符串操作和算法设计。
摘要由CSDN通过智能技术生成

题目链接

https://www.lanqiao.cn/problems/1071/learning/

题目大意

找出给定字符串每个前缀中的最长真前缀,使得该前缀剩下的真后缀是上述真前缀的前缀
(真前/后缀:不包含自身的非空前/后缀)。
并统计这些最长真前缀的长度之和(不存在记为0)。

解题思路

40 p t s 40pts 40pts

暴力循环模拟
1、遍历每一个前缀
2、从大到小取proper前缀,如果满足取完proper前缀的后缀是所取proper前缀的前缀,则返回最大周期长度

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
from math import ceil
def is_prefix(s, sub):
    return s[: len(sub)] == sub
def max_circle(s):
    tail = len(s) - 1
    middle = ceil(len(s) / 2) - 1
    for size in range(tail, middle, -1):
        pre, suf = s[: size], s[size:]
        if is_prefix(pre, suf):
            return size
    return 0


if __name__ == '__main__':
    n = int(input())
    s = input()

    cnt = 0
    for i in range(2, n + 1):
        cnt += max_circle(s[: i])
    print(cnt)
100 p t s 100pts 100pts

1、对于字符串 s s s,其前缀函数定义为:对于每个下标 i i i s [ 0 : i ] s[0:i] s[0:i] 的真前后缀最长相等长度。
2、在此基础上,考虑真前后缀的最短相等长度,记为最短前缀函数。
∣ s [ 0 : i ] ∣ − m i n ( s [ 0 : i ] 的公共前缀后缀 ) |s[0:i]|−min(s[0:i]的公共前缀后缀) s[0:i]min(s[0:i]的公共前缀后缀)
希望周期尽可能的大,也就是希望真前后缀相等长度尽可能的短
最后只需要根据题意,排除前后缀重叠的情况,即可得到答案。

AC_Code

python程序:

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def max_fix(s):
    max_same = [0] * len(s)
    for i in range(1, len(s)):
        j = i - 1
        while j >= 0:
            pi = max_same[j]
            if s[i] == s[pi]:
                max_same[i] = pi + 1
                break
            j = pi - 1
    return max_same
def min_fix(s):
    min_same = max_fix(s)
    for i in range(1, len(s)):
        j = i   # initial j as i > 0
        while min_same[j]:    # ensure j and pi > 0
            min_same[i] = min_same[j]
            j = min_same[j] - 1  # worst j is 0
    return min_same
if __name__ == '__main__':
    n = int(input())
    s = input()
    min_same = min_fix(s)
    cnt = 0
    for i in range(1, n):
        if min_same[i]:
            size = i + 1
            if min_same[i] <= size // 2:
                cnt += size - min_same[i]
    print(cnt)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是雨玮a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值