第四章 串和数组 (主要kmp算法)

第四章

题目:串的模式匹配

给定一个主串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

时间: 2024-08-25 05:00:25

第四章 串和数组 (主要kmp算法)的相关文章

perl5 第四章 列表和数组变量

第四章 列表和数组变量 by flamephoenix 一.列表二.数组--列表的存贮  1.数组的存取  2.字符串中的方括号和变量替换   3.列表范围  4.数组的输出  5.列表/数组的长度  6.子数组  7.有关数组的库函数 一.列表  列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如:(1, 5.3 , "hello" , 2),空列表:().  注:只含有一个数值的列表(如:(43.2) )与该数值本身(即:43.2 )是不同的,但它们可以互相转化或赋值. 

&lt;深入理解C指针&gt;学习笔记和总结 第四章 指针和数组

数组是一个什么玩意: 数组和指针我的理解,有相同之处也有不同之处.因有相同之处,因此一些资料上说,数组和指针本质是相同的.因有不同之处,因此也有一些资料上说,数组和指针是不一样的. 相同之处: 数组名字和指针名字都代表了一个地址. 如:int num[10];num是数组名.函数开辟了一个存储十个整数类型的空间,而num是他们的首地址. int *p; p=(int *)malloc(10*sizeof(int));类似的,p也指向了首地址. 不同之处是,num[10]中的空间位置是在栈中,而

数据结构例程——串的模式匹配(KMP算法)

本文针对数据结构基础系列网络课程(4):串中第5课时串的模式匹配(KMP算法). 问题:串的模式匹配 KMP算法: #include <stdio.h> #include "sqString.h" void GetNext(SqString t,int next[]) /*由模式串t求出next值*/ { int j,k; j=0; k=-1; next[0]=-1; while (j<t.length-1) { if (k==-1 || t.data[j]==t.d

数据结构(C语言版)-第4章 串、数组和广义表

补充:C语言中常用的串运算 调用标准库函数 #include<string.h> 串比较,strcmp(char s1,char s2) 串复制,strcpy(char to,char from)串连接,strcat(char to,char from) 求串长,strlen(char s) 4.1  串 串(String)----零个或多个字符组成的有限序列 串的存储结构:顺序存储.链式存储 顺序存储表示 typedef struct{ char *ch; //若串非空,则按串长分配存储区,

C语言数据结构——第四章 串

四.串 4.1-串的基本概念 串的定义 串是由数字.字母或其他字符组成的有限序列,一般记为 StringName = “a[0]a[1]a[2]···a[i]···a[n-1]”(n>0,0<=i<=n-1) 其中StringName是串名,双引号内的序列是该串的值,n为串的长度,i为某一字符在该串中的下标 串的常用术语 串的长度:串中包含字符个数即为串的长度 空串:串中不包含任何字符时被称为空串,此时串的长度为0 空格串:由一个或多个空格组成的串被称为空格串,它的长度是串中空格的个数

第四章 串的基本操作【数据结构】

运行截图. 自己太久没有这样用过指针了,总是用不好~~ 下次自己申请了一个指针,就得初始化,不然在判断是否为空的操作下,会导致程序停止运行.(传说中的敲代码5分钟,debug2小时又被我碰上了,泪目). #include<stdio.h> #include<string.h> #include<stdlib.h> #include<malloc.h> #define ERROR 0 #define OK 1 #define MAXSIZE 1000 type

《数据结构》之串的模式匹配算法——KMP算法

1 //串的模式匹配算法 2 //KMP算法,时间复杂度为O(n+m) 3 #include <iostream> 4 #include <string> 5 #include <cstring> 6 using namespace std; 7 8 //-----串的定长顺序存储结构----- 9 #define MAXLEN 255 //串的最大长度 10 typedef struct { 11 char ch[MAXLEN + 1]; //存储串的一维数组 12

串的模式之kmp算法实践题

给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not Found”. 本题旨在测试各种不同的匹配算法在各种数据情况下的表现.各组测试数据特点如下: 数据0:小规模字符串,测试基本正确性: 数据1:随机数据,String 长度为 10510^510?5??,Pattern 长度为 101010: 数据2:随机数据,String 长度为 10510^510

数据结构 第4章 串、数组和广义表 单元小结(1)重点 BF算法

BF算法 考试必考 !!!!!背下来!!!! int lndex_BF(string s,string t,int pos) {//返回模式t在主串s中第pos个字符开始第一次出现的位置下标 //若不存在,则返回值为-1 //其中,t非空,1<=pos<=StrLength(s) int i,j; i = pos-1;//下标 j = 0;//下标 while(i<s.length()&&j<t.length()){ if(s[i] == t[j]) { ++i;