暴力算法

//暴力算法
int index(SString S,SString T,int pos)
{int i=pos,j=1;while(i<=S[0]&&j<=T[0]){if(S[i]==T[j]){++i;++j;}else {i=i-j+2;j=1;}}if(j>T[0])return i-T[0];else return 0;} 

kmp算法


next[]数组的求法:
例子:abaabcac

模式串的下标从1开始

  1. 第一位固定为0;
  2. 第二位固定为1;
  3. 从第三位(i)开始(其余的每一位都如此),
    从该位 (i) 的前一位开始,从右向左寻找子串
    从模式串的头部(最左边),从左向右寻找子串
    找到两头子串的最大相同的个数
    把最大相同的个数的下一位的索引给next[i]
//next函数算法
void get_next(SString T,int next[])
{int j; int i=1;next[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;next[i]=j;}else j=next[j];}
}
int Index_KMP(SString S,SString T,int pos)
{   int next[MAXSTRLEN+1]; get_next(T,next);int i=pos;  int j=1;while(i<=S[0]&&j<=T[0])//i j都不超过其串的长度{//失配 //1:失配,当j==0时,则目标主串的检测指针前进一位,模式串检测指针回到T[1].进行下一趟的比较//2:失配,当j>0时,那么在下一趟比较时,模式串的起始位置为Tnext[j],目标主串S的检测指针不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//继续比较后继字符 }else j=next[j];//模式串向右移动 }if(j>T[0]) return i-T[0];//匹配成功 else return 0;
}

kmp算法改进版
例子:abaabcac

求nextval[]数组:(需要根据next[]数组来求)
1.

void get_nextval(SString T,int nextval[])
{int j; int i=1;nextval[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;if(T[i]!=T[j])nextval[i]=j;else nextval[i]=nextval[j];}else j=nextval[j];}
}int Index_KMP_val(SString S,SString T,int pos)
{   int nextval[MAXSTRLEN+1]; get_nextval(T,nextval);int i=pos;  int j=1;while(i<=S[0]&&j<=T[0])//i j都不超过其串的长度{//失配 //1:失配,当j==0时,则目标主串的检测指针前进一位,模式串检测指针回到T[1].进行下一趟的比较//2:失配,当j>0时,那么在下一趟比较时,模式串的起始位置为Tnext[j],目标主串S的检测指针不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//继续比较后继字符 }else j=nextval[j];//模式串向右移动 }if(j>T[0]) return i-T[0];//匹配成功 else return 0;
}

包含三个算法的全部程序代码

#include <stdio.h>  // printf(); scanf()
#include <stdlib.h> // exit()
#include <malloc.h> // malloc()
#include <time.h>   // srand((unsigned)time(NULL));
#include <string.h>// 函数结果状态代码
#define TRUE    1
#define FALSE   0
#define OK      1
#define ERROR   0
#define INFEASIBLE  -1
#define OVERFLOW    -2// Status是函数的类型,其值是函数结果状态代码
typedef int Status;// #define ElemType int  // 也可以用宏定义确定ElemType类型
typedef int ElemType;
// Status是函数的类型,其值是函数结果状态代码 -----串的定长顺序存储表示-----
#define MAXSTRLEN 255                            // 用户可在255(1个字节)以内定义最大串长
typedef unsigned char SString[MAXSTRLEN + 1];   // 0号单元存放串的长度Status StrAssign(SString &T, char *chars) {if(strlen(chars) > MAXSTRLEN)return ERROR;else {T[0] = strlen(chars);       // 0号单元存放串的长度for(int i=1; i<=T[0]; i++)T[i] = *(chars+i-1);return OK;}
}Status StrCopy(SString &T, SString S) {for(int i=0; i<=S[0]; i++)T[i] = S[i];return OK;
}int StrCompare(SString S, SString T) {int i;for(i=1; i<=S[0] && i<=T[0]; ++i)if(S[i] != T[i])return S[i]-T[i];return S[0]-T[0];
}int StrLength(SString S) {return S[0];
}Status StrEmpty(SString S) {if(S[0] == 0)return TRUE;elsereturn FALSE;
}Status Concat(SString T, SString S1, SString S2) {// 若未截断,则返回TRUE;否则返回FALSE。int i;if(S1[0]+S2[0] <= MAXSTRLEN)   // 未截断{for(i=1; i<=S1[0]; i++)     // 将串S1赋给TT[i] = S1[i];for(i=1; i<=S2[0]; i++)     // 将串S2赋给T中已有串S1的后面T[S1[0]+i] = S2[i];T[0] = S1[0] + S2[0];       // 新串的长度return TRUE;} else if(S1[0] < MAXSTRLEN) {  // 截断S2的部分字符序列for(i=1; i<=S1[0]; i++)     // 将串S1赋给TT[i] = S1[i];for(i=1; i<=MAXSTRLEN-S1[0]; i++)// 将串S2未截断的部分赋给T中已有串S1的后面T[S1[0]+i] = S2[i];T[0] = MAXSTRLEN;return FALSE;} else {                        // 截断(仅取S1)for(i=1; i<=MAXSTRLEN; i++) // 将串S1赋给TT[i] = S1[i];T[0] = MAXSTRLEN;return FALSE;}
}//Concat 算法 4.2
// 初始条件:串S存在,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1。
// 操作结果:用Sub返回串S的第pos个字符起长度为len的子串。
Status SubString(SString Sub, SString S, int pos, int len) {int i;if(pos<1 || pos>S[0] || len<0 || len>S[0]-pos+1)return ERROR;for(i=1; i<=len; i++)Sub[i] = S[pos+i-1];Sub[0] = len;return OK;
}void StrPrint(SString T) {for( int i = 1; i<= T[0]; i++)printf("%c ", T[i]);printf("\n");
}
//将模式串的next函数值存入到数组next中
//next函数算法
void get_next(SString T,int next[])
{int j; int i=1;next[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;next[i]=j;}else j=next[j];}
}//利用模式串T的next函数求T在主串S中第pos个字符之后的位置
//KMP算法 其中T非空  1<=pos<=StrLength(S) void get_nextval(SString T,int nextval[])
{int j; int i=1;nextval[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;if(T[i]!=T[j])nextval[i]=j;else nextval[i]=nextval[j];}else j=nextval[j];}
}int Index_KMP(SString S,SString T,int pos)
{   int next[MAXSTRLEN+1]; get_next(T,next);int i=pos;  int j=1;while(i<=S[0]&&j<=T[0])//i j都不超过其串的长度{//失配 //1:失配,当j==0时,则目标主串的检测指针前进一位,模式串检测指针回到T[1].进行下一趟的比较//2:失配,当j>0时,那么在下一趟比较时,模式串的起始位置为Tnext[j],目标主串S的检测指针不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//继续比较后继字符 }else j=next[j];//模式串向右移动 }if(j>T[0]) return i-T[0];//匹配成功 else return 0;
}int Index_KMP_val(SString S,SString T,int pos)
{   int nextval[MAXSTRLEN+1]; get_nextval(T,nextval);int i=pos;  int j=1;while(i<=S[0]&&j<=T[0])//i j都不超过其串的长度{//失配 //1:失配,当j==0时,则目标主串的检测指针前进一位,模式串检测指针回到T[1].进行下一趟的比较//2:失配,当j>0时,那么在下一趟比较时,模式串的起始位置为Tnext[j],目标主串S的检测指针不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//继续比较后继字符 }else j=nextval[j];//模式串向右移动 }if(j>T[0]) return i-T[0];//匹配成功 else return 0;
}//暴力算法
int index(SString S,SString T,int pos)
{int i=pos,j=1;while(i<=S[0]&&j<=T[0]){if(S[i]==T[j]){++i;++j;}else {i=i-j+2;j=1;}}if(j>T[0])return i-T[0];else return 0;} int main()
{   int x;int number;int pos;char  c[MAXSTRLEN+1],d[MAXSTRLEN+1];SString S;SString T;printf("输入字符串S(主串):");scanf("%s",c);if(!StrAssign(S, c)) {printf("串长超过MAXSTRLEN=%d,程序正常退出。\n", MAXSTRLEN);exit(0);}printf("输入字符串T(模式串):");scanf("%s",c);if(!StrAssign(T, c)) {printf("串长超过MAXSTRLEN=%d,程序正常退出。\n", MAXSTRLEN);exit(0);}    //  StrPrint(S);//  StrPrint(T);printf("输入要在主串开始的位置pos:");scanf("%d",&pos);printf("选择要是用的算法1(暴力算法)/2(kmp算法next)/3(kmp算法nextval):");scanf("%d",&x);if(x==1){number=index(S, T, pos);printf("%d",number);}else if(x==2){int next1[MAXSTRLEN+1];get_next( T,next1);for(int i=1;i<=T[0];i++){printf("%d ",next1[i]);}printf("\n"); number=Index_KMP(S,T,pos);printf("%d",number);}else if(x==3){int nextval1[MAXSTRLEN+1];get_nextval( T,nextval1);for(int i=1;i<=T[0];i++){printf("%d ",nextval1[i]);}printf("\n"); number=Index_KMP_val(S,T,pos);printf("%d",number);}return 0;}

数据结构——模式匹配kmp算法相关推荐

  1. c语言数据结构kmp中next计算,数据结构——关于KMP算法中next函数的详细解析

    以前看到数据结构中字符串的模式匹配时,花了半天的时间,才把KMP算法中的next函数整明白了,结果过了几天在看到这时,只记得next[j+1]=next[j]+1,但是有时候能套公式正确算出,有时候就 ...

  2. 数据结构:KMP算法 串的模式匹配算法(全网最详细)

    目录 KMP模式匹配算法 简述 KMP模式匹配算法原理 如果人眼来优化的话,怎样处理         接下来我们自己来发现j的移动规律: 这一段公式证明了我们为什么可以直接将j移动到k而无须再比较前面 ...

  3. 字符串模式匹配KMP算法详解(Python语言)

    问题描述 主串为 ′ababcabcacbab′ ′ a b a b c a b c a c b a b ′ 'ababcabcacbab',模式串为 ′abcac′ ′ a b c a c ′ 'a ...

  4. 数据结构-串-KMP算法详解(Next数组计算)(简单易懂)

    文章目录 KMP介绍 一.求Next数组 前后缀表 求最长公共前后缀 最长相等前后缀表转Next数组 二.使用Next数组来匹配字符串 总结 本文章就专讲kmp,暴力匹配就不讲了(我相信能搜索kmp的 ...

  5. 每日算法练习——模式匹配KMP算法(看毛片算法?)

    知识补充: 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息来 ...

  6. 【数据结构】KMP算法

    简介 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的核心是利用匹配 ...

  7. 数据结构之KMP算法(转)

    申明:此篇博文为转载博文,原博文地址:https://www.cnblogs.com/yjiyjige/p/3263858.html 什么是KMP算法: KMP是三位大牛:D.E.Knuth.J.H. ...

  8. 【数据结构】KMP算法(c语言)

    #include <stdio.h> #include <string.h> #include <stdlib.h>typedef int Position; // ...

  9. 算法笔记:简单的字符串模式匹配-KMP算法(与BF算法对比时间复杂度)

    简单的讲就是字符串不回溯. #include<stdio.h> #include<stdlib.h> #include<string.h>int countBF = ...

最新文章

  1. 2013年3月百度之星B题
  2. 每日一皮:这张图送给正在努力改Bug的你
  3. vue/cli 3.0 与 2.0脚手架怎样mock数据
  4. struts2教程(8)--文件上传下载
  5. Shell数组相关操作
  6. 016-Spring Boot JDBC
  7. centos6.5配置Hadoop环境,运行wordcount例子
  8. dplyr | 数据处理函数的功能速查!dplyr包中的十类操作函数汇总(下篇)
  9. linux下vi编辑器的命令大全,linux下VI编辑器命令大全(超级完整版)
  10. HTTP, WWW-Authenticate, Authorization 验证授权 | Apache验证 | Python处理
  11. python在工程管理专业的应用_工程大数据在水利工程建设管理的应用
  12. 如何打印被加密的PDF文件
  13. python网络爬虫实践收获_python网络爬虫实习报告
  14. 公司内外网同时使用方法
  15. 网络远程控制原理及技术实现
  16. 利用免费的必应 Bing 自定义搜索打造站内全文搜索
  17. 新冠病毒数据分析报告
  18. 宝宝防晒 夏日妈妈的日常工作
  19. Spark GraphX 图算法的理解
  20. Mixed Content: The page was loaded over HTTPS,blocked the content must be served over HTTPS.

热门文章

  1. ASP.NET Core 导入导出Excel xlsx 文件
  2. 程序员求职面试三部曲之一:选择合适的工作单位
  3. 框架实现修改功能的原理_JAVA集合框架的特点及实现原理简介
  4. php获取邮箱内容吗,php正则验证email邮箱及抽取内容中email的例子
  5. [转]Flask --- 框架快速入门
  6. LeetCode之Add Digits
  7. Ubuntu之12.04常用快捷键——记住这些你就是高手啦!
  8. 链表之判断一个链表是否为回文结构(二)
  9. 软件项目组织管理(一)项目管理概述
  10. 掌握深度学习,为什么要用 PyTorch、TensorFlow 框架?