博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第四章 串和数组 (主要kmp算法)
阅读量:7063 次
发布时间:2019-06-28

本文共 1927 字,大约阅读时间需要 6 分钟。

第四章

题目:串的模式匹配

给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。

(用KMP算法,就是不用再回溯,

最前面的k个字符和j之前的最后k个字符是一样的:P[1~ k] == P[j-k ~ j-1])

1、先定义一个串的顺序存储结构,因为不需要出插入和删除操作,所以选用了顺序存储

typedef struct {    char ch[maxlen + 2];    int length;}sstring;

2、为了方便自己对于kmp的理解,所以用以下代码来实现数组下标从1开始

void add(sstring &s, char temp[]) {       s.ch[0] = ' ';    strcat(s.ch, temp);    s.length = strlen(s.ch) - 1;}

3、按照题目要求写了一部分主函数

int main() {  int result = 0;     cin >> temp;    add(s, temp);    cin >> temp;    add(t, temp);    需要一个求位置的函数    求位置时在回溯过程中需要一个知道回溯到哪里的函数 }

发现需要两个函数,于是开始写下面的函数

4、用一个函数来求模式串的next函数并存入数组nextval。

其中有个初始化如下,我起初不理解,后面想明白了:j已经在最左边了,不可能再移动了,所以这时候要应该是i指针后移

nextval[1] = 0;

找到next函数的主要过程:

while (i < t.length) {  //t为模式串        if (j == 0 || t.ch[i] == t.ch[j]) {  //相同则继续往后移,找到最长相同前后缀            j++;            i++;            if (t.ch[i] != t.ch[j]) {  //前面已经+1,匹配下一个是否相等,                nextval[i] = j;  //如果不同  把j位置给next            }            else {  //如果相同                nextval[i] = nextval[j];  //则i 的位置等于j的位置,最长相同前后缀同时加            }        }        else  //如果不等,则重置j            j = nextval[j];//next[j]为之前最长相同前后缀    }

主要是:

当T[i] != P[j]时,有T[i-j ~ i-1] == P[1 ~ j],由P[1 ~ k] == P[j-k ~ j-1]   —>  必然:T[i-k ~ i-1] == P[1 ~ k]

5、利用模式串T的next函数求T在主串S中第几个字符之后的位置。

1)表示位置相同的变量

int result = 0;

2)如果相同则右移

if (j == 0 || s.ch[i] == t.ch[j]) {             j++;            i++;        }

3)不同则回溯

else {            j = nextval[j];         }

4)匹配成功时,result即为第一个字符出现的位置

if (j > t.length) {  //当最后匹配成功就是比主串多1时        result = i - t.length;    }

6、写完函数后写函数声明

oid add(sstring &s, char temp[]);void getnext(sstring T, int next[]);int KMP(sstring s, sstring t, int next[]);

7、补充主函数

int main(){    int result = 0;    cin >> temp;    add(s, temp);    cin >> temp;    add(t, temp);    getnext(t, nextval);    result = KMP(s, t, nextval);    cout << result;    return 0;}

 

转载于:https://www.cnblogs.com/MRBC/p/10708357.html

你可能感兴趣的文章
要吃鲷鱼到岛上钓
查看>>
图片自适应宽度显示正方形
查看>>
如何提高队列的消息处理效率
查看>>
Java中的代理
查看>>
Android深度探索读后感 第三章
查看>>
Aidl
查看>>
顺序表的静态建立
查看>>
「技巧」如何快速安装 Sketch 插件
查看>>
C#中对文件的操作小结
查看>>
事件流
查看>>
苹果中毒员工称症状复发:入住当地医院遭拒
查看>>
numpy数组及处理:效率对比
查看>>
javascript事件模型
查看>>
线性表
查看>>
spring 的权限控制:security
查看>>
python基础===map和zip的用法
查看>>
常见复杂指针声明的解析(很详细)
查看>>
Java反射(Reflection)获取运行时类的结构
查看>>
获取系统热键链表windbg脚本 GetHotkeys windbg script
查看>>
3.2、Android Studio在物理设备中运行APP
查看>>