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的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
随机推荐
- CentOS7系统局域网内配置本地yum源解决cannot find a valid baseurl for repo
一. 问题详情 因为服务器无法连接外网,所有直接用yum安装某些功能将受到影响,报错如下: Error: Cannot find a valid baseurl for repo: base ...
- 1、获取ip地址
1.获取ip地址 System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() .Select(p => p. ...
- keepalived的配置文件
! Configuration File for keepalived global_defs { notification_email { # acassen@firewall.loc # fail ...
- 快速排序的python实现
def quick_sort(array, left, right): if left < right: base_index = division(array, left, right) qu ...
- Kubernetes部署DNS
前言 阅读地址 http://thoreauz.com/2017/04/16/docker/Kubernetes%E9%83%A8%E7%BD%B2DNS%E5%92%8CDashboard/ Kub ...
- 【串线篇】spring boot配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件 (1)–file:./config/ ...
- wannafly25 E 01串
链接 wannafly25 E 01串 给出一个\(01\)串,有两种操作,操作一是将某一个位置的数字修改,操作二是询问某一个区间,将这个区间看做\(1\)个二进制数,可以随意加减\(2\)的幂次,问 ...
- Ubuntu 18.04 安装 Octave 5.1
最新版目前只能通过编译安装.折腾了半天终于搞定: 需要使用apt-get install先把各种 dependencies 安装好. 编译JIT需要安装sudo apt-get install llv ...
- vue对特殊特性的研究
key 预期:number | string key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes.如果不使用 key,Vue 会使用一种最大限度减少 ...
- iText导出PDF(图片,水印,页眉,页脚)
项目需要导出PDF,导出的内容包含图片和文本,而且图片的数量不确定,在网上百度发现大家都在用iText,在官网发现可以把html转换为PDF,但是需要收费,那就只能自己写了. 在开始之前先在网上百度了 ...