首页 > 其他分享 >day9

day9

时间:2023-01-20 00:01:45浏览次数:30  
标签:匹配 前缀 day9 int needle next charAt

1、KMP算法

  1. KMP的作用:KMP用于字符串匹配

  2. KMP的主要思想:当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。

  3. 前缀表

    1. 什么是前缀表?

      记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。

    2. 前缀表的作用?

      前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。(要在文本串中查找是否出现过一个模式串)

    3. 为什么可以使用前缀表可以回退到重新匹配的位置?

      因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面重新匹配就可以了。

  4. 前缀表与next数组

    1. 前缀表 ==》 next数组
    2. 前缀表统一减一 ==》 next数组
    3. 前缀表右移一位,初始位置为-1 ==》next数组
  5. 使用next数组进行匹配

  6. 时间复杂度

    1. 其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。
    2. 暴力的解法显而易见是O(n × m),所以KMP在字符串匹配中极大地提高了搜索的效率。

2、leetcode28 找出字符串中第一个匹配项的下标

  1. 代码实现

    class Solution {
        public int strStr(String haystack, String needle) {
            if(needle.length() == 0){
                return 0;
            }
    
            int[] next = new int[needle.length()];
            getNext(next, needle);
    
            int j=0; // 因为next数组里记录的起始位置为0
            for(int i=0;i<haystack.length();i++){
                while(j>0 && needle.charAt(j) != haystack.charAt(i)){// 不匹配
                    j = next[j-1];// j 寻找之前匹配的位置
                }
                if(needle.charAt(j)==haystack.charAt(i)){// 匹配,j和i同时向后移动
                    j++;// i的增加在for循环里
                }
                if(j==needle.length()){// 文本串s里出现了模式串t
                    return i-needle.length()+1;
                }
            }
    
            return -1;
    
        }
    
        //前缀表作为next数组
        public void getNext(int[] next, String s){
            int j = 0; //j指向前缀末尾,初始化为0
            next[0] = 0; //当字符串长度为1时,相同前后缀的长度为0
            for(int i=1; i<s.length(); i++){//i指向后缀末尾
                while(j>0 && s.charAt(j) != s.charAt(i)){
                    j = next[j-1]; //循环不变量:每次匹配不成功时,从当前位置的上一位在next数组中找回退位置
                }
                if(s.charAt(j)==s.charAt(i)){
                    j++;
                }
                next[i]=j; // 将j(前缀的长度)赋给next[i]  
            }
        }
    }
    

3、leetcode459 重复的子字符串

  1. 代码实现

    class Solution {
        public boolean repeatedSubstringPattern(String s) {
            if(s.length()==0){
                return false;
            }
            int[] next = new int[s.length()];
            getNext(next,s);
            int len = s.length();
            if (next[len - 1] != 0 && len % (len - (next[len - 1] )) == 0) {
                return true;
            }
            return false;
        }
    
        //前缀表作为next数组
        public void getNext(int[] next, String s){
            int j = 0;
            next[0] = 0;
            for(int i=1; i<s.length(); i++){
                while(j>0 && s.charAt(j)!=s.charAt(i)){
                    j=next[j-1];
                }
                if(s.charAt(j)==s.charAt(i)){
                    j++;
                }
                next[i]=j;
            }
        }
    }
    

标签:匹配,前缀,day9,int,needle,next,charAt
From: https://www.cnblogs.com/hzj-bolg/p/17062320.html

相关文章

  • 代码随想录day9 LeetCode 459重复的子字符串 字符串总结
    459重复的子字符串https://leetcode.cn/problems/repeated-substring-pattern/classSolution{public:int*getNext(strings){//创建next[i]为最长相等前后缀长度的......
  • Day9:学习循环结构
    循环结构while循环do…while循环for循环在java5中引入了一种主要用于数组的增强型for循环while循环while是最基本的循环,它的结构为:while(布尔表达式){......
  • day9
    ......
  • 学习python-Day93
    bs4搜索文档树rombs4importBeautifulSouphtml_doc="""<html><head><title>TheDormouse'sstory</title></head><body><pid="myp"class="title">asdfasdf<b......
  • 学习python-Day92
    requests高级用法https和http的区别https=http+ssl或者tsl(ssl或tsl是加密的证书)注意:没有认证的机构就是没有签发证书,访问的时候,浏览器会提示不安全的。ssl认证......
  • 学习python-Day91
    一、支付宝支付介绍支付类型:支付宝支付微信支付需要备案过域名云闪付API,SDKsdk:第三方sdk,基于API封装的官方sdk支付宝沙箱环境Sandbox:程序的虚拟执行环境......
  • 学习python-Day90
    一、课程板块相关分析以及创建建表思路:有个课程表通过类型字段区分划分不同课,所以这三种课的表字段是是不一样的。一种课设计一张表FreeCourse 免费课程Course 实......
  • 百题_每日一题Day9
    输出9*9乘法口诀表。1.占位符使用:print('%d*%d=%d'%(i,j,i*j),end='\t')--这里将三个变量的值依次填充。2.题解:'''遍历输出'''foriinrange(1,10):forj......
  • 函数与递归(day9)
    本章目的不是为了学会递归,而是通过递归学习函数在递归过程中在内存的储况以及递归函数的语句执行顺序。问题1:通过递归拆分数字实例​voidprint(intx){if(x>9){pr......
  • LeetCode刷题记录.Day9
    快乐数题目链接202.快乐数-力扣(LeetCode)classSolution{public:intgetSum(intn){intsum=0;while(n){sum+=(n%10)*......