实验室学习第五次总结

今天学习的是KMP算法。

该算法是由三个外国人发明的,他们名字的首字母构成了该算法的名字。

先简单的讲一下这个算法是干什么的。粗暴的说这事一个高效的寻找字符串的算法,它的存在,大大的缩短了查找的时间。其巧妙之处在于……

看得出来,非常的巧妙😉😂。
见上图,在查找中,开头就有ABAB的重复。按照一般暴力的算法,子串的第一个A将会与主串中的第一个B对其,然后继续匹配。但是在KMP算法中,将会这样子:

KMP算法将会标记子串已经匹配过的前缀和后缀,并在下一次的查询中,子串的前缀直接跳转至主串的后缀,并进行匹配。于是就这样,直到完成匹配。

有一道题目非常好
P3375 【模板】KMP
这道题目生动的诠释了什么是kmp
 

# 【模板】KMP

## 题目描述

给出两个字符串 $s_1$ 和 $s_2$,若 $s_1$ 的区间 $[l, r]$ 子串与 $s_2$ 完全相同,则称 $s_2$ 在 $s_1$ 中出现了,其出现位置为 $l$。  
现在请你求出 $s_2$ 在 $s_1$ 中所有出现的位置。

定义一个字符串 $s$ 的 border 为 $s$ 的一个**非 $s$ 本身**的子串 $t$,满足 $t$ 既是 $s$ 的前缀,又是 $s$ 的后缀。  
对于 $s_2$,你还需要求出对于其每个前缀 $s'$ 的最长 border $t'$ 的长度。

## 输入格式

第一行为一个字符串,即为 $s_1$。  
第二行为一个字符串,即为 $s_2$。

## 输出格式

首先输出若干行,每行一个整数,**按从小到大的顺序**输出 $s_2$ 在 $s_1$ 中出现的位置。  
最后一行输出 $|s_2|$ 个整数,第 $i$ 个整数表示 $s_2$ 的长度为 $i$ 的前缀的最长 border 长度。

## 样例 #1

### 样例输入 #1

```
ABABABC
ABA
```

### 样例输出 #1

```
1
3
0 0 1
```

以上是题目原文

#include<iostream>//P3375 【模板】KMP
using namespace std;
int kmp[1000005];
void lessonl()
{
    int lena, lenb, pos = 0;
    string a, b;
    cin >> a >> b;
    a = '0' + a;
    b = '0' + b;
    lena = a.size() - 1;
    lenb = b.size() - 1;
    for (int i = 2; i <= lenb; i++)
    {
        while (pos && b[i] != b[pos + 1])
            pos = kmp[pos];
        if (b[pos + 1] == b[i])
            pos++;
        kmp[i] = pos;
    }
    pos = 0;
    for (int i = 1; i <= lena; i++)
    {
        while (pos && a[i] != b[pos + 1])
            pos = kmp[pos];
        if (b[pos + 1] == a[i])
            pos++;
        if (pos == lenb)
        {
            printf("%d\n", i - lenb + 1);
            pos = kmp[pos];
        }
    }
    for (int i = 1; i <= lenb; i++)
        printf("%d ", kmp[i]);
}
int main()
{
    lessonl();
    return 0;
}

这是答案代码。
代码还是不能完全理解呢,但是整体的思路还是知道的。
明天还是得做做相关的题目呢。
 

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值