KMP子串匹配(只能匹配出唯一子串)
using namespace std;
#include <iostream>
#include<string> //自定义字符串存储结构String(包括char数组、length长度)
#define maxlen 20
typedef struct {
char ch[maxlen];
int length;
}String; //初始化s
void strInit(String& s) {
s.length = 0;
s.ch[0] = s.length; //ch[0]空着用来存长度,初始化为0
} //s判空
bool strEmpty(String s) {
if (s.length == 0) //如果长度为0代表空串
return true;
else
return false;
} //获得s长度
int strLength(String s) {
cout << "长度打印:" << s.length << endl;;
return s.length; //或者s.ch[0]
} //将string字符串赋值到s数据结构中用char数组保存
String strAssign(String &s, string t) {
int i = 1; //从1开始存字符,0空着用来存长度
s.length =0;
cout << "字符串打印:";
for (int j = 0; j < t.length(); j++) {
s.ch[i] = t[j];
cout << s.ch[i] << " ";
s.length++;
i++;
}
s.ch[0] = s.length; //0空着用来存长度
cout << endl;
return s;
} /////////上面都是一些基础函数,下面开始KMP算法/////////////////////////////////////////////
//step1:求出子串的next[j]值【普通版】
void get_next(String s, int next[]) {
int j = 1, k = 0;
next[1] = 0; //next[1]值必须填0
while(j<s.length){
if (s.ch[j] == s.ch[k] || k == 0) {
j++;
k++;
next[j] = k;
}
else
k = next[k];
}
//打印看看
cout <<"打印next[i]为: ";
for (int i = 1; i <=s.length; i++)
cout << next[i] << " ";
cout << endl;
} //step1:求出子串的nextval[j]值【改进版,只记录不相同值的索引,避免j的无效回退。2个方法2选1即可】
void get_nextval(String s, int nextval[]) {
int j = 1, k = 0;
nextval[1] = 0; //nextval[1]值必须填0
while (j < s.length) {
if (s.ch[j] == s.ch[k] || k == 0) {
j++;
k++;
if (s.ch[j] != s.ch[k])
nextval[j] = k;
else
nextval[j] = nextval[k];
}
else
k = nextval[k];
}
//打印看看
cout << "打印nextval[i]为: ";
for (int i = 1; i <= s.length; i++)
cout << nextval[i] << " ";
cout << endl;
} //step2:开始主串中匹配子串,并返回第一个元素出现的位置
int index3(String s, String t, int next[]) {
int i = 1, j = 1;
while (i <= s.length && j <= t.length) { //找到最后一个字符为止
if (j == 0||s.ch[i] == t.ch[j]) { //如果字符不相同或者j为0了,i和j同步往后移1位
i++;
j++;
}
else
j = next[j]; //j回退到next[j]位置
}//while结束,s和t至少有一个找到头了
if (j > t.length) {
//打印看看
cout << "index3打印子串为: ";
for (int m = i - t.length; m < i; m++)
cout << s.ch[m] << " ";
cout << endl;
return (i - t.length); //或者i-t.length,返回i最开始的位置
}
else
return 0;
} void main() {
int next[20];
int nextval[20];
string sf = "aaaacabcaaaabab";
string sz = "aaaab"; String ss ,tt;
strInit(ss); //初始化主串
strInit(tt); //初始化子串
strAssign(ss, sf); //把字符串放进数据结构
strAssign(tt, sz); //把字符串放进数据结构
strLength(ss); //获取长度
strLength(tt); //获取长度 get_next(tt, next); //获得子串各个next值
cout << "用next的index3 i下标:" << index3(ss, tt, next) << endl; get_nextval(tt, nextval); //获得子串各个nextval值
cout << "用nextval的index3 i下标:" << index3(ss, tt, nextval) << endl;
}
KMP子串匹配(只能匹配出唯一子串)的更多相关文章
- “全栈2019”Java异常第十一章:重写方法时只能抛出父类异常子集
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- 一个try可以跟进多个catch语句,用于处理不同情况,当一个try只能匹配一个catch
一个try可以跟进多个catch语句,用于处理不同情况.当一个try只能匹配一个catch. 我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前 ...
- 为什么HTML中的多个空格或是回车在浏览器上只能显示出一个?
我们在学习HTML的时候可能书本或是老师会告诉我们一件事,就是在HTML中不管我们在两个文本之间加上多少连续的空格或是回车,到了浏览器里面只能显示出一个来.但是我们从来不知道为什么. 原因很简单,因为 ...
- 循环匹配出图片地址(即src属性)
<script type="text/javascript"> //思路分两步:作者(yanue). //1,匹配出图片img标签(即匹配出所有图片),过滤其他不需要的 ...
- 请用正则表达式匹配出QQ号(假设QQ号码为5—10位);
请用正则表达式匹配出QQ号(假设QQ号码为5—10位): 解答: ^ \d{5,10}$
- KMP算法,匹配字符串模板(返回下标)
//KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...
- HDU-2087 剪花布条 字符串问题 KMP算法 查匹配子串
题目链接:https://cn.vjudge.net/problem/HDU-2087 题意 中文题咯 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条, ...
- KMP算法——字符匹配
暴力匹配: 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢? 如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置, ...
- 一个简易的kmp教学并给出java实现
简单介绍一下问题 给定source字符串,找出target字符串出现的首位 例如 source 为“abddabddabc” target 为 “abddabc” 从第一位开始比较 |a b d ...
随机推荐
- UF_CSYS 坐标系操作
Open C UF_CSYS_ask_csys_info 获取WCS坐标系的原点坐标和矩阵标识UF_CSYS_ask_matrix_of_object 获得对象 ...
- 【NX二次开发】判断部件是否已修改(判断部件是否需要保存)UF_PART_is_modified();
判断部件是否已修改(判断部件是否需要保存)UF_PART_is_modified(); 注意:函数需要输入原型,不要输入事例.事例转原型:UF_ASSEM_ask_prototype_of_occ() ...
- 从零开始学架构(三)UML建模
文章大纲 1. 文章介绍 2. UML概述 3. 静态模型 4. 动态模型 5. UML建模的一般过程 一.文章介绍 1.1为什么学习UML (1)UML是一种软件架构的模型表现方法,用于项 ...
- 重新整理 .net core 实践篇—————工作单元模式[二十六]
前言 简单整理一下工作单元模式. 正文 工作单元模式有3个特性,也算是其功能: 使用同一上下文 跟踪实体的状态 保障事务一致性 工作单元模式 主要关注事务,所以重点在事务上. 在共享层的基础建设类库中 ...
- CMD批处理(1)——批处理常用命令总结
echo 打开回显或关闭回显功能,或显示消息.如果没有任何参数,echo命令将显示当前的回显设置. 命令格式1:echo [{on|off}] 命令格式2:echo [message] 例.在命令 ...
- 简单聊聊Ehcache缓存
最近工作没有那么忙,有时间来写写东西.今年的系统分析师报名已经开始了,面对历年的真题,真的难以入笔,所以突然对未来充满了担忧,还是得抓紧时间学习技术. 同事推了一篇软文,看到了这个Ehcache,感觉 ...
- 单片机项目中使用新IC芯片的调试方法
前两天,一位小伙伴咨询我一款新IC芯片怎么使用,借此机会我顺便把我日常工作中经常用到的一种调试方法介绍给小伙伴们,希望对对大家有所帮助.准备仓促,文中难免有技术性错误,欢迎大家给予指正,并给出好的建议 ...
- CRM系统如何帮助企业管理多条业务线的?
在如今的市场环境中,许多企业为了提高销售效率,增加业绩收入,都会选择使用CRM客户关系管理系统来帮助进行对客户和销售的管理.CRM系统能够帮助企业在不同的产品线上同时开展营销活动.各个销售团队能够独立 ...
- CentOS-Docker搭建Nextcloud
下载镜像 $ docker pull nextcloud 运行镜像 $ docker run -d --restart=unless-stopped --name nextcloud -v /home ...
- Docker:redis容器使用redis.conf启动失败,不报错
查看redis.conf配置信息 daemonize no :redis默认是不作为守护进程使用的,这也就是说为什么在你不修改配置文件时直接使用redis-server /redis/redis.co ...