停课竞赛第二天2020/10/27

本文详细介绍了字符串匹配算法KMP,包括其基本原理和例题。接着讲解了Trie数据结构及其在字符串集合操作中的应用。并查集部分阐述了其快速处理、基本原理、优化和例题。手写堆的实现和作用也被提及,包括插入、删除、修改和查询操作。最后是对学习过程的小结。
摘要由CSDN通过智能技术生成

一、KMP

        首先第一个算法是KMP字符串匹配,这是个很有难度的算法。
        字符串模式匹配:可以简单地理解为在目标(字符串)中寻找一个给定的模式(也是字符串),返回目标和模式匹配的第一个子串的首字符位置。通常目标串比较大,而模式串则比较短小。
        KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。
        KMP的算法思想还是比较容易理解的,但是解释起来会比较抽象,(其实是我不会解释。) 所以就插入一个大学学长写的博客吧!
字符串 KMP算法与AC自动机算法

例题

s串中查找p串,输出起始下标

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

const int N = 1e6 + 10;

int lenp, lens;
char p[N], s[N];
int ne[N];

int main() {
   
    scanf("%d %s", &lenp, p + 1);
    scanf("%d %s", &lens, s + 1);
    for (int i = 2, j = 0; i <= lenp; i++) {
   
        while (j && p[j + 1] != p[i]) j = ne[j];
        if (p[j + 1] == p[i]) j++;
        ne[i] = j;
    }
    for (int i = 1, j = 0; i <= lens; i++) {
   
        while (j && p[j + 1] != s[i]) j = ne[j];
        if (p[j + 1] == s[i]) j++;
        if (j == lenp)
        {
   
            printf("%d ", i - lenp);
            j = ne[j];
        }
    }
    return 0;
}

二、Trie

        一种高效存储和查找字符串集合的数据结构。

例题1

维护一个字符串集合,支持两种操作:

“I x”向集合中插入一个字符串x;
“Q x”询问一个字符串在集合中出现了多少次。

#include <cstdio>

using namespace std;

const int N = 1e5 + 10;

int son[N][26], cnt[N], idx;
char str[N];

void insert(char str[]) {
   
    int p = 0;
    for (int i = 0; str[i]; i++) {
   
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++idx;
        p = son[p][u];
    }
    cnt[p]++;
}

int query(char str[]) {
   
    int p = 0;
    for (int i = 0; str[i]; i++) {
   
        int u = str[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}

int main() {
   
    int n;
    scanf("%d", &n);
    while (n--) {
   
        char op[2];
        scanf("%s %s", op, str);
        if (op[0] == 'I') insert(str);
        else printf("%d\n", query(str));
    }
    return 0;
}
例题2

在给定的N个整数 A 1 , A 2 … … A N A_{1},A_{2}……A_{N} A</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值