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. SpringBoot数据访问(二) SpringBoot整合JPA

    JPA简介 Spring Data JPA是Spring Data大家族的一部分,它可以轻松实现基于JPA的存储库.该模块用于增强支持基于JPA的数据访问层,它使我们可以更加容易地构建使用数据访问技术 ...

  2. 干货 | LuatOS BSP移植教程,简单到复制粘贴!!!

    LuatOS本着自身的开源特性,可以很轻松的嵌入到很多微处理器和微控制器.今天简要讲下如何移植这套系统,上手比较简单,看完基本就会了. 要想做移植,就要先了解需要移植芯片的SDK,LuatOS依赖于F ...

  3. ld-linux-x86-64消耗大量的CPU

    1.现象: 服务器CPU使用率很高 top查看cpu使用进程: 2.进程用户是oracle,根据spid查看是否是数据库进程,经过查询发现:不是数据库内部的进程 select a.sql_id,a.s ...

  4. Golang写文件的坑

    Golang写文件一般使用os.OpenFile返回文件指针的Write方法或者WriteString或者WriteAt方法,但是在使用这三个方法时候经常会遇到写入的内容和实际内容有出入,因为这几个函 ...

  5. Java 7的javax.net.ssl.SSLHandshakeException

    Java 7的javax.net.ssl.SSLHandshakeException 现象:Java7通过httpsURLConnection建立HTTPS连接,异常如下: javax.net.ssl ...

  6. MySQL之where条件数据筛选

    语法: -- select * from 表名 where 条件; 测试数据: -- 建表语句 create table `student` ( `sid` int(11) primary key a ...

  7. 16、lamp的搭建

    搭建web02服务器作为web01的负载均衡服务器: httpd和nginx配置比较相似,也有虚拟主机,一个http服务需要配置多个站点,基于ip(基本用不到).端口(内部网站).域名(外部网站): ...

  8. 10、ssh中scp、sftp程序详解

    每次都是全量拷贝,rsync是增量拷贝 10.1.scp的基本用法: -r:拷贝目录; -p: 保持属性: -l:限速设置; scp -P52113 /etc/hosts lc@172.16.1.41 ...

  9. 230th Weekly Leetcode Contest

    题目二 题目描述 5690. 最接近目标价格的甜点成本  难度:中等-中等 题解 解法一:三进制状态压缩 考虑到baseCosts.toppingCosts的长度最多都为10,每一种辅料都有加0.1. ...

  10. buu 不一样的flag

    一.查壳 二.拖入ida,分析 从这里和51到53行的代码,基本判断这是一个迷宫题,并且是5行5列的一个迷宫.我当时感觉到一个奇怪的地方是 第一个,我自己想明白是因为可能是int型,数字占了4个字节, ...