简介:

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. 你不知道的hostname命令

    一般hostname可以获取主机名,但是hostname实际上可以做更多的事情. 让我们先来看看它的帮助. Usage: hostname [-b] {hostname|-F file} set ho ...

  2. readlink 查看符号链接的文件的内容

    1. 命令功能 readlink 查看软链接文件里的真实内容. 2. 语法格式 readlink [option]  file 参数 参数说明 -f 后跟软链接文件 3. 使用范例 范例1 查看文件链 ...

  3. neuoj1472 yuki的氪金之旅(倒置树状数组

    这题一直re不造为啥..后来yww大神把树状数组“倒过来”就过了,倒过来的好处是算sum(d[i]+1)就行,不涉及除法,不用求逆元. 题意:初始手牌颜值是0,一共抽卡n次,第i次抽卡有pi的概率能抽 ...

  4. CSS3 Animations

    CSS Animations 是CSS的一个模块,它定义了如何用关键帧来随时间推移对CSS属性的值进行动画处理.关键帧动画的行为可以通过指定它们的持续时间,它们的重复次数以及它们如何重复来控制. an ...

  5. 【leetcode】1091. Shortest Path in Binary Matrix

    题目如下: In an N by N square grid, each cell is either empty (0) or blocked (1). A clear path from top- ...

  6. HashMap接口测试

    package com.iotek.map; import java.util.Collection;import java.util.HashMap;import java.util.Map;imp ...

  7. POJ 2253 Frogger ( 最短路变形 || 最小生成树 )

    题意 : 给出二维平面上 N 个点,前两个点为起点和终点,问你从起点到终点的所有路径中拥有最短两点间距是多少. 分析 : ① 考虑最小生成树中 Kruskal 算法,在建树的过程中贪心的从最小的边一个 ...

  8. socket函数库简单封装

    #pragma once #ifndef WINSOCK_H #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib" ...

  9. [CSP-S模拟测试]:Dinner(二分)

    题目描述 清儿今天请好朋友们吃饭,一共$N$个人坐在坐在圆桌旁.吃饭的第一步当然是点餐了.服务员拿来了$M$份菜单.第$i$个人阅读菜单并点出自己喜欢的菜需要花费时间$T_i$.当一个人点完菜之后,就 ...

  10. ThreadLocal学习资料

    下面的这一段代码运行起来,就会发生线程安全问题: 启动两个线程,同时去修改 name 属性值. package com.liwei.thread; /** * 下面的代码演示了线程安全发生的由来 * ...