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子串匹配(只能匹配出唯一子串)的更多相关文章

  1. “全栈2019”Java异常第十一章:重写方法时只能抛出父类异常子集

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  2. 一个try可以跟进多个catch语句,用于处理不同情况,当一个try只能匹配一个catch

    一个try可以跟进多个catch语句,用于处理不同情况.当一个try只能匹配一个catch. 我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前 ...

  3. 为什么HTML中的多个空格或是回车在浏览器上只能显示出一个?

    我们在学习HTML的时候可能书本或是老师会告诉我们一件事,就是在HTML中不管我们在两个文本之间加上多少连续的空格或是回车,到了浏览器里面只能显示出一个来.但是我们从来不知道为什么. 原因很简单,因为 ...

  4. 循环匹配出图片地址(即src属性)

    <script type="text/javascript"> //思路分两步:作者(yanue). //1,匹配出图片img标签(即匹配出所有图片),过滤其他不需要的 ...

  5. 请用正则表达式匹配出QQ号(假设QQ号码为5—10位);

    请用正则表达式匹配出QQ号(假设QQ号码为5—10位): 解答: ^ \d{5,10}$

  6. KMP算法,匹配字符串模板(返回下标)

    //KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...

  7. HDU-2087 剪花布条 字符串问题 KMP算法 查匹配子串

    题目链接:https://cn.vjudge.net/problem/HDU-2087 题意 中文题咯 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条, ...

  8. KMP算法——字符匹配

     暴力匹配: 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢? 如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置, ...

  9. 一个简易的kmp教学并给出java实现

    简单介绍一下问题 给定source字符串,找出target字符串出现的首位 例如 source   为“abddabddabc” target 为 “abddabc” 从第一位开始比较 |a b d ...

随机推荐

  1. What is maven?

    Introduction Maven, a Yiddish word meaning accumulator(累加器) of knowledge, began as an attempt to sim ...

  2. 题解 P3605 [USACO17JAN]Promotion Counting P

    分块\(yyds\) ----关于线段树合并的题我用分块过掉这件事 题目传送门 先说正解 正解当然是线段树合并等一类做法了 至于解析...出门右转题解区第一篇 (就是他让我看不懂,然后用分块打的\(Q ...

  3. 「10.16晚」序列(....)·购物(性质)·计数题(DP)

    A. 序列 考场不认真读题会死..... 读清题就很简单了,分成若干块,然后块内递增,块外递减,同时使最大的块长为$A$ B. 购物 考场思路太局限了,没有发现性质, 考虑将$a_{i}$,排序前缀和 ...

  4. 【复习】Listening and Reading Comprehension

    短对话 M: Why do you declare the news that you're pregnant on your blog directly? W: I'm so excited tha ...

  5. typescript 中的 infer 关键字的理解

    infer 这个关键字,整理记录一下,避免后面忘记了.有点难以理解呢. infer infer 是在 typescript 2.8中新增的关键字. infer 可以在 extends 条件类型的字句中 ...

  6. 在微信小程序中使用阿里图标库Iconfont

    首先想要使用图标,只用上图的五个iconfont相关文件就可以了.(下下来的文件iconfont.wxss开始是.css的后缀,手动改成.wxss就可以在小程序中使用) 然后在app.wxss中引入i ...

  7. 一次性讲清楚spring中bean的生命周期之一:getSingleton方法

    要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ...

  8. 根据所处位置提取单元格内容的函数(left、right、mid)和查找字符串位于单元格内容第几位的函数(find)

    1.从左到右提取:left(value,num_chars) 注释:value为操纵单元格,num_chars表示截取的字符的数量 2.从右往左提取:right(value,num_chars) 注释 ...

  9. Linux定时任务-cronie

    1.cronie服务介绍 Linux crontab(cronie)是用来定期执行程序的命令. 当安装完成操作系统之后,默认就会启动此任务调度命令. crond 命令每分钟会定期检查是否有要执行的工作 ...

  10. 源码搭建Zabbix4.0.23LTS监控系统

    实验环境 centos 7.5 主机名 IP地址 配置 应用 controlnode 172.16.1.120/24 4核/8G/60G java-1.8.0-openjdk zabbix serve ...