简介:

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++实现)的更多相关文章

  1. Sunday字符串匹配算法

    逛ACM神犇的博客的时候看到的这个神奇的算法 KMP吧,失配函数难理解,代码量长 BF吧,慢,很慢,特别慢. BM吧,我不会写... 现在看到了Sunday算法呀,眼前一亮,神清气爽啊. 字符串匹配算 ...

  2. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

    前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...

  3. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  4. Sunday算法:字符串匹配算法进阶

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  5. 字符串匹配算法:Sunday算法

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  6. 字符串匹配算法之Sunday算法(转)

    字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...

  7. Boyer-Moore 字符串匹配算法

    字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...

  8. KMP单模快速字符串匹配算法

    KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...

  9. 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解

    一.前言   在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...

随机推荐

  1. Taro -- 获取用户手机号

    1. 安装 Taro 脚手架工具 安装 Taro 开发工具 @tarojs/cli 使用 npm 或者 yarn 全局安装 $ npm install -g @tarojs/cli $ yarn gl ...

  2. rabbit例子

    https://blog.csdn.net/csm201314/article/details/76377214 #include <SimpleAmqpClient/SimpleAmqpCli ...

  3. bzoj4408 [Fjoi 2016]神秘数 & bzoj4299 Codechef FRBSUM 主席树+二分+贪心

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4299 https://lydsy.com/JudgeOnline/problem.php?id ...

  4. Mysqldump导入数据库很慢的解决办法

    https://blog.csdn.net/xizaihui/article/details/53103049 1.MySQLdump导出的SQL语句在导入到其他数据库的时候会相当慢,甚至几十秒才处理 ...

  5. 【leetcode】912. Sort an Array

    题目如下: Given an array of integers nums, sort the array in ascending order. Example 1: Input: [5,2,3,1 ...

  6. 一个KVO 实现WKWebView加载进度条的例子 (注意最后移除观察者)

    // // OpenWebViewController.m // Treasure // // Created by 蓝蓝色信子 on 16/7/29. // Copyright © 2016年 GY ...

  7. Docker Swarm学习教程【转载】

    Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docke ...

  8. php array_splice()函数 语法

    php array_splice()函数 语法 作用:从数组中移除选定的元素,并用新元素取代它.dd马达价格 语法:array_splice(array,start,length,array) 参数: ...

  9. FFT IP核调用与仿真之SCALE压缩因子设置

    关于FFT IP核的配置,网上有很多相关的资料可以参考,但是唯独涉及到scaled压缩因子设置这个参数,资料却非常匮乏,这是个什么参数,应该整么设置,设置后对结果输出会有什么影响,整样才能知道它设置的 ...

  10. ECharts t图表组件使用心得

    1.使用较多的是“柱状图”和“折线图”: 2.数据列的展示不能够直接输入字符串,正确的做法是将字符串转换成数字类型,这样在生成的图表上才会显示最大值和最小值: 3.对上 1 点的补充,数据列应该使用数 ...