zoukankan      html  css  js  c++  java
  • BF算法 + KMP算法

    准备:

    字符串比大小:比的就是字符串里每个字符的ASCII码的大小。(其实这样的比较没有多大的意义,我们关心的是字符串是否相等,即匹配等)

    字符串的存储结构:同线性表(顺序存储+链式存储)

      顺序存储结构是一组地址连续的存储单元来存储字符串中的字符序列;按照预定义的大小,为每个定义的字符串变量分配一个固定长度的存储区,一般用定长数组来定义。——空间分配不灵活,但是字符串一般都是连在一起表述的,”断章取义“的情况并不多,所以习惯上我们还是会直接定义一个足够长度的存储区来存储

      链式存储结构

     

    BF算法:

      BoyFriend 、Brute Force

      朴素的模式匹配算法,其核心思想是:

      ——有两个字符串S和T,长度分别为N和M。首先S[1]和T[1]比较,若相等,则再比较S[2]和T[2],一直到T[M]为止;若S[1]和T[1]不等,则T向右移动一个字符位置,与S[2]进行比较,而后再依次进行比较。

      ——该算法最坏情况下要进行M*(N-M+1)次比较,时间复杂度为O(M*N)。____效率低下。

    (注:在这里S为主串,T为子串,这种子串的定位操作通常称作串的模式匹配)

      存在回溯,需要重头来过,效率低下。

     

    KMP算法:

      克努特-莫里斯-普拉特算法,大大的避免重复遍历的情况(避免不必要的回溯)

      问题由模式匹配串(子串)决定,不是由目标串决定。

      给模式匹配串添加个k数组(即next数组),这是一个”智能“的数组,因为它指导着模式匹配串下一步该用第几号元素进行匹配

        ——k数组元素:k[1]=0,k[2]=1,然后从不匹配元素位置开始往前查看,探讨其前缀与后缀相同元素个数,k[i]即相同元素个数+1。

    (解读next数组:当模式匹配串T失配的时候,next数组对应的元素指导应该用T串的哪个元素进行下一轮的匹配)

    (注:模式匹配串和目标串的下标都是从1开始,0下标存储串的长度)

    next数组获取示例演示:

    next数组获取代码展示:

     1 //i(后缀)
     2 //j(前缀)
     3 void get_next(String T, int *next)
     4 {
     5     j = 0;
     6     i = 1;
     7     next[1] = 0;
     8     while( i < T[0])
     9     {
    10         if(0 == j || T[i] == T[j])
    11         {
    12             i++;
    13             j++;
    14             next[i] = j;
    15         }
    16         else
    17         {
    18             j = next[j];//j回溯
    19         }
    20     }
    21     //因为前缀是固定的,后缀是相对的。
    22 }

    next数组获取优化:

    优化next数组代码如下:

     1 //优化
     2 //i(后缀)
     3 //j(前缀)
     4 void get_next(String T, int *next)
     5 {
     6     j = 0;
     7     i = 1;
     8     next[1] = 0;
     9     while( i < T[0])
    10     {
    11         if(j == 0 || T[i] == T[j])
    12         {
    13             i++;
    14             j++;
    15             if(T[i] != T[j])//判断
    16             {
    17                 next[i] = j;
    18             }
    19             else
    20             {
    21                 next[i] = next[j];
    22             }
    23         }
    24         else
    25         {
    26             j = next[j];//j回溯
    27         }
    28     }
    29     //因为前缀是固定的,后缀是相对的。
    30 }

    最后KMP.c

     1 //若存在,返回子串T在主串S第pos个字符之后的位置
     2 //若不存在返回0
     3 int Index_KMP(Stirng S, Stirng T, int pos)
     4 {
     5     int i = pos;
     6     int j = 1;
     7     int next[255];
     8     
     9     get_next(T, next);
    10     
    11     while(i <= S[0] && j <= T[0])
    12     {
    13         if(0 == j || S[i] == T[j])
    14         {
    15             i++;
    16             j++;
    17         }
    18         else
    19         {
    20             j = next[j];
    21         }
    22     }
    23     if(j > T[0])
    24     {
    25         return i - T[0];
    26     }
    27     else
    28     {
    29         return 0;
    30     }
    31 }

     

     

  • 相关阅读:
    【Python入门 】—— 关于Numpy的使用
    CSP 201512 | 201604考试题目
    【Python入门】 —— 用pycharm写7道简单的PTA题目吧!
    【Python入门】 —— 用pycharm写两道超简单的PTA题目~
    Crypto.AES 报错 | TypeError: Object type <class 'str'> cannot be passed to C code
    windows安装Pytorch报错:from torch._C import * ImportError: DLL load failed: 找不到指定的模块”解决方案
    Python中的self通俗理解(自己理解的,自我感觉比官网解释要容易懂)
    python获取token数据
    python根据对象的实例获取对象的属性值
    oracle查询某个字段不为空的sql语句
  • 原文地址:https://www.cnblogs.com/xymqx/p/4396861.html
Copyright © 2011-2022 走看看