学习日记:2022年2月8日

今天写的第一个题目kmp

具体的题目我也没有看,直接到网上搜索了一下kmp算法

首先kmp算法解决的问题就是从一个母串中快速查找到子串的位置

题目的要求也刚好就是找出子串在母串中的位置

以题目中的例子来说

已知一个母串
ABABABC

已知一个子串

ABA

第一种方法,暴力破解,也是第一次看见这个题目最先会想到的方法

拿母串进行一个一个比较,如果完全匹配那么就输出

第一次匹配

能够完全匹配,就输出一个1,移动到下一个

第二次匹配

 第一个就不对,继续移动 

第三次匹配

 成功匹配,输出3,继续移动

后面的第四次匹配,第五次匹配都不成功

使用这样的方法来匹配的话,需要匹配的次数就是5

如果我们使用kmp算法来求的话过程是这样的

首先第一次匹配

输出1

第二次匹配

输出3

第三次匹配

 最终匹配的次数就是3

其中的算法当然也不是就是找开头相同这么简单

我们再换一个例子

已知母串

已知子串 

第一次匹配

第二次匹配

 第三次匹配,这个时候就会和我们最开始的暴力破解不一样了

首先我们定位到不相同的点,也就是编号为9的位置,首先我们可以确保9之前的位置都是能够匹配的,接下来我们就要找一个位置,接下来就是找能够匹配的子串里面是否有后缀串等于前缀串,如果有,我们就匹配前缀串的后一个

能够匹配的子串为:ABCDAB,前缀等于后缀的刚好也有AB=AB,移动子串,使之前缀串的后一个进行匹配

 第四次匹配,上次匹配的位置是9,而9之前的位置都是匹配了的,这个就是kmp算法的妙处

我们继续前一步操作,此时没有能够相等的前缀串和后缀串了。于是我们就把子串的开头移过来

 第五次匹配

 最终成功匹配

这个就是kmp算法的思路

其中最重要的就是遇到不匹配的位置如何进行跳转

我最开始的思路就是用另外一个数组来对子串进行一个类似于定位的操作

我们把子串ABCDABD拆开来看

如果我们第一个就错了,我们就需要往后移动一个

如果是AB第二个B错了,我们需要定位到A的位置,所以B定位的位置是0(从0开始)

如果是ABC第三个C错了,我们需要定位到A的位置,C定位的位置是0

如果是ABCD第四个D错了,我们还是要定位到A的位置重新开始,D的定位位置也是0

当ABCDA的第五个A错了,我们定位的位置依旧是A的位置,所以A定位的位置也是0

当ABCDAB的第六个B错了,我们定位的位置就是最前面B的位置了,可以参考一下前面的例子。所以当前的B定位的位置就是1了

当ABCDABD的第七个D错了,前后缀都没有相同的,所以定位的位置也是0

最终出来的一个定位表格就是

A        B        C        D        A        B        D

0        0        0        0          0        1        0

这个也是题目中结果的最后一行要填的东西

但是使用这种方法就会发现ABA得出来的是000

这个就是这个题目和网上的内容不同的地方

题目中的定位包含当前的位置,而网上的大多都不包含当前的位置。

总体来说,包含会有一个-1的烦恼,不包含要好一些

这个题目的难点也是吧这个表格给计算出来

如果是abababc

第一个肯定是0

第二个也是0

第三个能和前面的a匹配也就是1

第四个能够匹配出一对ab,也就是2

第五个能够匹配出一对aba,也就是3

第六个能够匹配出一对abab,也就是4

第七个没有匹配,也就是0

最终的出来的结果就是这样子

 如果找规律的话不难发现,如果能够匹配的话就是前一种情况加上当前的字母

从第三个开始a,ab,aba,abab

如果和前面不匹配的情况如何呢???

比如果ababcccababc

前面的直接跳过,我们直接来到不能匹配的地方

 下标为5的时候不能够和前者形成匹配,于是我们就找到前者的前者是否能够匹配(回溯,判断是否相等)前者为4,回溯的位置为2,不相等,继续回溯,最终达到了0依然不相等,所以标记为0

使用同样的方法,来到下一个特殊的点

 最后一个点,下标为12的时候,首先不能和前者进行匹配,

前者为11,不相等,回溯,回溯的位置为5,b!=a

继续回溯,回溯的位置为3和前者a相等,最终定位的点为最后一次回溯的位置也就是3

最终的代码如下

#include<iostream>
#include<string.h>
using namespace std;
char mon[1000006];//母串
char son[1000006];//子串
int pla[1000006];//前缀长度
int prepare()//求前缀最长border长度
{
    pla[0]=0;
    int len=strlen(son);
    int present=1;
    while(present<len)
    {
        //判断是否和前者匹配
        if(son[present]==son[pla[present-1]])
        pla[present]=pla[present-1]+1;
        else
        {
            int front=pla[present-1];
            // 定位到能够匹配的点
            while(son[front]!=son[present]&&front)
            {  
            // cout<<front<<endl;
                front=pla[front-1];
            }
            //如果能够匹配
            if(son[front]==son[present])
            pla[present]=front+1;
            else    
            pla[present]=0;
        }
        present++;
    }
    return 0;
}
int check()
{
    int present=0;
    int len=strlen(mon);
    // cout<<len<<endl<<endl<<endl;
    for(int i=0;i<len;)
    {
        //是否遇到了不相同的节点
        if(son[present]!=mon[i])
        {
            // cout<<present<<' '<<i<<endl;
            //如果第一个就不匹配的情况
            if(present==0)
            i++;

            //匹配完成的情况
            if(present==strlen(son))
            {
                cout<<i-present+1<<endl;
                present=pla[present-1];
            }

            //匹配还没有完成的情况
            else
            {
                present=pla[present-1];   
            }
            continue;
        }
        i++;
        present++;
    }

    // 判断最后一个
    if(present==strlen(son))
    {
        cout<<len-present+1<<endl;
    }
    return 0;
}
int main()
{
    cin>>mon>>son;
    prepare();
    check();
    for(int i=0;i<strlen(son);i++)
    cout<<pla[i]<<' ';
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大数据开发中的shell学习日记可以包括以下内容: 1. 学习Linux命令和shell脚本:作为大数据开发者,在Linux下进行开发是常见的,因此了解一些基本的Linux命令和编写shell脚本的技能是必备的。 2. 学习Django:Django是一个常用的Python Web框架,对于大数据开发来说,掌握Django可以帮助你构建数据分析和机器学习的应用程序。 3. 数据分析与机器学习:大数据开发中经常需要进行数据分析和机器学习的工作,因此学习相关的技术和算法是必要的。可以参考一些前人的经验贴和教程,了解常见的数据分析和机器学习方法。 4. 大数据组件:了解大数据开发中常用的组件,如Hadoop、Spark等,掌握它们的基本原理和使用方式。 5. 前端内容:虽然大数据开发主要是后端的工作,但了解一些基本的前端知识也是有帮助的,比如HTML、CSS和JavaScript。 6. 数据架构:了解大数据开发中的数据架构,包括数据采集层、数据存储与分析层、数据共享层和数据应用层等,这对于设计和搭建大数据系统是很重要的。 此外,你还可以在牛客网等平台上深入学习和交流大数据开发的经验和知识。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java版斗地主源码-Interview-Summary:回顾这两来学了些什么和日记,private](https://download.csdn.net/download/weixin_38592548/19393922)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [程序员必备学习资源资料库!!!免费开发书籍中文版大全](https://blog.csdn.net/qq_32146369/article/details/106194267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [大数据平台架构--学习日记(一)](https://blog.csdn.net/lp279579561/article/details/104746083)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值