📜  门| GATE CS 2019 |第 45 题(1)

📅  最后修改于: 2023-12-03 14:58:20.341000             🧑  作者: Mango

题目介绍

题目来源:GATE CS 2019

题目编号:第 45 题

该题目为计算机科学专业考试门类题目,需要程序员具有较高的计算机知识和编程技能。

题目描述

该题目要求实现一种支持字符串匹配的算法。给定两个字符串S和P,其中S是文本字符串,P是模式字符串。算法需要返回S中匹配P的所有子串的起始位置。例如,当S="ABCABCAB",P="ABC"时,算法需要返回[0,3,6]。

输入格式

首先输入两个整数m和n,表示字符串S和P的长度。接下来两行分别为S和P字符串。

输出格式

输出一个整数数组,表示所有匹配P的子串在S中的起始位置。

样例输入

9 3
ABCABCAB
ABC

样例输出

[0, 3, 6]

算法思路

该题目可以采用经典的字符串匹配算法——KMP算法进行解决。KMP算法是一种利用字符串之间的重复性质来加速字符串匹配的算法。

其基本思路是在模式串P中搜索一个最长的、既是自身的前缀,也是P的后缀的字符串。这个字符串是模式串P的next数组中的值,记为next[j]。在匹配的过程中,当匹配到文本串S中的某一字符与模式串P匹配失败时,根据next数组的值来调整模式串P的位置。具体实现可见下方的代码实现。

代码实现

def KMP(S, P):
    m = len(S)
    n = len(P)

    next = [0] * n
    i, j = 1, 0

    while i < n:
        if P[i] == P[j]:
            j += 1
            next[i] = j
            i += 1
        elif j > 0:
            j = next[j - 1]
        else:
            next[i] = 0
            i += 1

    res = []
    i, j = 0, 0

    while i < m:
        if S[i] == P[j]:
            i += 1
            j += 1
        elif j > 0:
            j = next[j - 1]
        else:
            i += 1

        if j == n:
            res.append(i - j)
            j = next[j - 1]

    return res

该算法的时间复杂度为O(m+n),空间复杂度为O(n)。