数据结构——模式匹配kmp算法

暴力算法

//暴力算法
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;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

互联网时代供应链

供应链是指围绕核心企业&#xff0c;从配套零件开始&#xff0c;制成中间产品以及最终产品&#xff0c;最后由销售网络把产品送到消费者手中的、将供应商&#xff0c;制造商&#xff0c;分销商直到最终用户连成一个整体的功能网链结构。供应链管理的经营理念是从消费者的角度&a…

win7 计算器 android,教你巧妙应用Win7计算器和时钟

正文最新的Win7是一种个性化设计极强的操作系统&#xff0c;在许多细节方面都做到了人性化设计。其功能的DIY性非常明显&#xff0c;是XP系统远远不能比的。今天我们要说的是Win7计算器和时钟&#xff0c;除了可以计算和时间之外我们还可以让他们有哪些妙用呢&#xff1f;我们左…

真实经历:整整一年了,他是这样从程序员转型做产品经理的

这是头哥侃码的第224篇原创每年年底&#xff0c;有不少企业都会对一年内辛勤劳作的员工量身定做一些奖项。发个奖杯&#xff0c;给点奖金&#xff0c;让那些没得奖的人看看&#xff0c;咱们公司有多么的关注员工的闪光点&#xff0c;优秀之处。用人所长&#xff0c;容人所短&am…

数据结构—— 基于二叉树的算术表达式求值

实验五 基于二叉树的算术表达式求值 数据结构——中序表达式求值&#xff08;栈实现&#xff09; 实验目的&#xff1a; 1.掌握二叉树的二叉链表存储表示和二叉树的遍历等基本算法。 2.掌握根据中缀表达式创建表达式树的算法 3.掌握基于表达式树的表达式求值算法。 实验内容&a…

数字标牌 android,【浩鑫推出全球首款英特尔方案+Android系统数字标牌播放器】PjTime.COM 新品快讯 Intel...

世界知名迷你准系统领导品牌&#xff0d;浩鑫Shuttle&#xff0c;秉承开拓创新&#xff0c;引领行业发展的传统&#xff0c;此次创造性的推出全球首款采用英特尔硬件方案搭载Android系统的NS01A数字标牌播放器&#xff0c;为整个数字标牌行业贡献了全新的硬件解决方案。英特尔方…

BCVP开发者说第3期:Adnc

沉静岁月&#xff0c;淡忘流年1项目简介AdncAdnc是一个轻量级的.NetCore微服务快速开发框架&#xff0c;同时也可以应用于单体架构系统的开发。框架基于JWT认证授权、集成了一系列微服务配套组件&#xff0c;代码简洁、易上手、学习成本低、开箱即用。    框架前端基于Vue、…

数据结构——二叉树的非递归算法

二叉树的非递归算法 先序遍历非递归算法1 先序遍历非递归算法2 非递归交换左右孩子算法 使用栈来实现二叉树的非递归算法 栈的基本算法 #include<stdio.h> #include<bits/stdc.h> typedef int Status; #define OK 1 #define ERROR 0 #define TRUE 1 #define …

python字符串的表示_Python字符串方法总结

Python字符串方法图示&#xff1a; &#xff08;温馨提示&#xff1a;对图片点右键——在新标签页中打开图片&#xff09;1、index() 定义&#xff1a;查找并返回指定str的索引位置&#xff0c;如果没找到则会抛异常&#xff08;查找的顺序是从左至右&#xff09;可以指定范围&…

Kuma 1.0 GA发布,70多项新功能和改进

喜欢就关注我们吧&#xff01;Kuma 1.0 GA 现已发布&#xff0c;包含了 70 多种新功能和改进。Kuma 是一个现代的通用服务网格控制平面&#xff0c;基于 Envoy 搭建&#xff0c;Envoy 是一个为云原生应用设计的强大的代理软件。Kuma 高效的数据平面和先进的控制平面&#xff0c…

还在犹豫是否迁移.NET5?这几个项目已经上线了!

.NET5正式发布有十多天&#xff0c;博客园、知乎、技术群都讨论的非常热烈。关于项目是否迁移.NET5的话题讨论的尤为热烈&#xff0c;作为.NET十年老司机要告诉你&#xff0c;.NET5的迁移势在必行&#xff0c;当下就是最好的时机&#xff01;犹豫项目是否升级到.NET5的&#xf…

Android切换泰语,Android应用内切换语言

首先扯点别的&#xff1a;这是第一次在简书上写东西&#xff0c;我突然明白为啥这么多人在简书上写东西了&#xff0c;因为没有广告啊&#xff0c;哈哈。最近接触到Android 应用内切换语言的问题&#xff0c;研究了两天&#xff0c;做个记录先。实现了中文&#xff0c;英文&…

工程勘察设计收费标准2002修订版_黑龙江省哈尔滨新区智能轨道快运系统1号线项目勘察设计招标...

黑龙江省哈尔滨新区智能轨道快运系统1号线项目勘察设计第一标段招标公告招标编号&#xff1a;JTZGSJ20200011.招标条件本招标项目黑龙江省哈尔滨新区智能轨道快运系统1号线项目勘察设计已由上级部门批准建设&#xff0c;项目业主为哈尔滨交通集团有限公司&#xff0c;建设资金来…

从 3.1 到 5.0 —— OpenReservation 更新记

OpenReservation 从 asp.net core 3.1 到 5.0IntroOpenReservation 是一个开源的预约系统&#xff0c;最初的版本是我们学校的活动室预约系统&#xff0c;现在正逐步变成一个更为通用的预约系统。.NET5 发布之后也是把这个项目更新到了 5.0。这个项目是一个做了很长时间的项目&…

数据结构——哈弗曼编码问题

实验六 基于哈夫曼树的数据压缩算法 【实验目的】 掌握哈夫曼树的构造算法。掌握哈夫曼编码的构造算法。 【实验内容】 问题描述 输入一串字符,根据给定的字符串中字符出现的频率建立相应的哈夫曼树, 构造哈夫曼编码表,在此基础上可以对压缩文件进行压缩(即编码),同时可以对 压…

relation does not exist报错是什么意思_为什么Zookeeper天生就是一副分布式锁的胚子?...

“ 什么是分布式锁&#xff1f;分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中&#xff0c;常常需要协调他们的动作。图片来自 Pexels如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源&#xff0c;那么访问这些资源的时候&#xff0…

netcore一键部署到linux服务器以服务方式后台运行

AntDeploy 是我开发一款开源一键发布插件将本地vs中的代码&#xff0c;一键打包&#xff0c;部署到任意的远程服务器部署方式支持 windows服务&#xff0c;linux服务&#xff0c;docker容器&#xff0c;iis支持增量发布(只更新有修改的)支持一键回滚(出了问题快速恢复)支持查看…

数据结构——基于 Dijsktra 算法的最短路径求解

实验七 基于 Dijsktra 算法的最短路径求解 【实验目的】 掌握图的邻接矩阵表示法&#xff0c;掌握采用邻接矩阵表示法创建图的算法。掌握求解最短路径的 Dijsktra 算法。 【实验内容】 问题描述 一张地图包括 n 个城市,假设城市间有 m 条路径(有向图),每条路径的长度 已知。给…

loadrunner录制事件为0_测试工具LoadRunner常见问题汇总,解决方案整理

LoadRunner是一种预测系统行为和性能的负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题&#xff0c;可适用于各种体系架构的自动负载测试&#xff0c;能预测系统行为并评估系统性能。我们在使用它进行测试的过程中经常会遇到一些错误&…

.NET应用如何优雅的实现功能定时开关

点击上方蓝字关注“汪宇杰博客”导语我们在打工的时候&#xff0c;总能遇到一种类型的需求&#xff1a;“我想要这个活动广告在双11期间才显示”&#xff0c;“我想要这个API在20号以后才开放”&#xff0c;可能你觉得这个需求没什么难的&#xff0c;写个时间判断不就行了&…

数据结构——图-迪杰斯特拉算法

问题描述 将图以邻接矩阵或邻接表存储&#xff0c;实现Dijkstra算法。 算法设计 迪杰斯特拉算法&#xff1a; 1.假设用带权的邻接矩阵arc&#xff0c;来表示带权有向图&#xff0c;arc[i][j]&#xff0c;表示弧<vi,vj>上的权值。若<vi,vj>不存在&#xff0c;则置…