Sunday 字符串匹配算法(C++实现)
简介:
Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法。其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率。
思路:
Sunday 算法 与 KMP 算法 一样是从前往后匹配,在匹配失败时关注的是主串中参加匹配的最末位字符的下一位字符。
1、如果该字符没有在模式串中出现则直接跳过,即移动位数 = 模式串长度 + 1;
2、否则,其移动位数 = 模式串长度 - 该字符最右出现的位置(以0开始) = 模式串中该字符最右出现的位置到尾部的距离 + 1。
代码:
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <vector> using namespace std; int main(){ string source = "Hello world,hello china,hello beijing";
string part = "beijing"; int index = ;//主要用来记录每一次的匹配位置
int i = ;//每一次新的循环起始位置
int j,next;//j用来记录子串的遍历位置,next记录下一个起始位置
while(i < source.length())
{
cout<<"Begin,index: "<<i<<" ,char: "<<source[i]<<endl;
next = i + part.length();
index = i;
j = ;
if(part[j]!=source[index])
{
//重新计算i的下一个位置
if(next < source.length())
{
int cut = ;
for(int z = ; z < part.length(); z++)
{
if(source[next]==part[z])
{
cut = z;
}
}
if(cut== && source[next]!=part[])
{
next++;
}
else
{
next -= cut;
}
}
i = next;
continue;
}
else
{
while(j<part.length())
{
if(part[j]!=source[index])
{
//重新计算i的下一个位置
if(next < source.length())
{
int cut = ;
for(int z = ; z < part.length(); z++)
{
if(source[next]==part[z])
{
cut = z;
}
}
if(cut== && source[next]!=part[])
{
next++;
}
else
{
next -= cut;
}
}
i = next;
break;
}
index++;
j++;
}
if(j==part.length())
{
break;
}
}
}
if(j==part.length())
{
cout<<"Yes,begin index is "<<index-j<<endl;
}
else
{
cout<<"No matching"<<endl;
} return ;
}
运行结果:
Begin,index: ,char: H
Begin,index: ,char: r
Begin,index: ,char: o
Begin,index: ,char: h
Begin,index: ,char: b
Yes,begin index is
分析:
第一次遍历,H开始:
Hello world,hello china,hello beijing
^
beijing H!=b
Hello world,hello china,hello beijing
^ ^next在这里
beijing # 由于next没有出现在子串里面,从next下一个的位置,也就是r开始第二轮遍历
Hello world,hello china,hello beijing
^ ^下一轮遍历的位置
beijing
第二次遍历,r开始:
Hello world,hello china,hello beijing
^ ^next
beijing r!=b
第三次遍历,o开始:
Hello world,hello china,hello beijing
^ ^next
beijing o!=b
第四次遍历,h开始:
Hello world,hello china,hello beijing
^ ^next
beijing h!=b next是e,此时,e在子串 "beijing" 里面能查到,所以下一次应该移动 "eijing" 这部分的长度
第五次遍历,b开始:
Hello world,hello china,hello beijing
^
beijing b==b
e==e
j==j
i==i
n==n
g==g
结束,能够匹配到
算法的时间复杂度:O(nm)
由于 Sunday 算法的偏移量比较大,较 KMP 算法来讲更容易实现且速度较快
Sunday 字符串匹配算法(C++实现)的更多相关文章
- Sunday字符串匹配算法
逛ACM神犇的博客的时候看到的这个神奇的算法 KMP吧,失配函数难理解,代码量长 BF吧,慢,很慢,特别慢. BM吧,我不会写... 现在看到了Sunday算法呀,眼前一亮,神清气爽啊. 字符串匹配算 ...
- 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!
前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...
- 字符串匹配算法之Sunday算法
字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...
- Sunday算法:字符串匹配算法进阶
背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...
- 字符串匹配算法:Sunday算法
背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...
- 字符串匹配算法之Sunday算法(转)
字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...
- Boyer-Moore 字符串匹配算法
字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...
- KMP单模快速字符串匹配算法
KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
随机推荐
- R语言抽样的问题
基本抽样函数sample sample(x,size,replace=F/T) x是数据集, size规定了从对象中抽出多少个数 replace 为F时候,表示每次抽取后的数就不能在下一次被抽取:T ...
- 洛谷P3158 [CQOI2011]放棋子 组合数学+DP
题意:在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列.有多少祌方法? 解法:这道题不会做,太菜了qwq.题解是看洛谷大佬的. 设C是组合数, ...
- utf8 中文
#include <iostream> #include <codecvt> #include <fstream> #include <string> ...
- Ansible笔记(2)---常用模块之文件操作
一.copy模块 1.1作用: copy模块是将ansible主机上的文件拷贝到远程受控主机 1.2常用参数: src参数 :用于指定需要copy的文件或目录. dest参数 :用于指定文件将被拷贝到 ...
- php内置函数分析之trim()
官方手册中: 类似函数还有两个:ltrim() 和 rtrim().分别处理字符串的左侧.右侧. trim()的具体实现位于:ext/standard/string.c /* {{{ proto st ...
- 查看ubuntu系统信息
root@k8s001:~/go/src/k8s.io/kubernetes# cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DI ...
- linux下caffe的命令运行脚本
参考:https://www.cnblogs.com/denny402/p/5076285.html 首先编译: make -j8 make pycaffe 注:下面的--solver=.... 等价 ...
- OC+RAC(六) 核心方法bind
-(void)_test6{ RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> ...
- php linux环境安装ftp扩展
1.进入PHP安装源码包,找到ext下的ftp,进入 cd /home/local/php-5.6.25/ext/ftp 2./usr/local/php/bin/phpize 3../configu ...
- oracle 字段信息
oracle 修改字段的长度alter table tablename modify column_name varchar2(32)alter table tablename modify (col ...