字符串匹配:sunday算法的实现。

sunday算法简单易懂,比KMP和BM都更容易理解。以后再补充KMP的算法。

竟然有人看我的文章。。。本来以为没人看的,所以就偷懒,原来的文字说明只有上面那一句,这下弄得我好羞愧。。。

来补充多点解释吧。

sunday算法是一个外国人在1990年发明的。。具体是谁忘记了,但他的名字里有sunday这个词,所以我猜这就是为什么叫sunday算法。

首先因为sunday算法每次的位置移动比BM算法还要大,所以程序更快也更有效率,在我的文章里,我把每次的位置移动称为喜闻乐见的跳跃运动。

先放到一个简单的例子里来看吧。

例如,在文本串“ABCDEFGABCDEFYABCHHYWYQCD”中寻找“HHYWYQ”

。。。。。。。。等等。我去做图。。这样纯手打不好讲。

EXCEL简单制图。。。别嫌弃。

首先“HHYWYQ”是一共六位,于是对齐上面的长文本串的前六位。

为了方便说明,我用string1表示那串长长长的文本串,用string2表示HHYWYQ这一小串。

用sunday实现在string1中查找是否存在string2,如果存在,则返回所在位置,不存在则返回0。

好了,开始比较。

但是只用比较第一位。即比较“A”和“H”。看图。

所有人都看见的跟我一样不相同吧?好的,不相同那我们就准备跳跃。下面加载跳跃运动。

找到String1中的strlen(string2)+1位,即第七位,这是我们的跳跃运动员。因为string2长度为6,所以就是比较第(6+1=)7位。看图。

就是string1中的G。找到第7位了,那么怎么比较呢?就是看在string2中有没有G这个字母。在这里显然是没有的。(具体原理稍后解释,现在我先把整个查找过程讲完。)

于是跳跃运动加载完毕。好了,起跳。看图。

华丽的跳了一大步,跳过了七位。正是因为sunday算法的跳跃步伐比BM的大,所以sunday的速度也快。

然后继续比较,这时就是比较string1的第8位和string2的第一位。看图。

还是一样,只需要比较这一位。比较结果是,不同。那么下面又开始加载跳跃运动。

这次的跳跃运动员就是string1的第14位,因为8+6=14,就是又加一次string2的长度。看图。

然后发现在HHYWYQ中有Y这个字母。于是跳跃运动加载失败。这下不能跳了。

然后就在string2中从右到左查找Y这个字母。从右到左第2个就是Y。

然后移动string2对齐右边的第一个Y,即移动2步。看图。

然后可以比较string2的第一位与相应的string1的位。看图。

不相同,那么就继续在string2中寻找还有没有Y。于是发现前面还有一个Y,所以不能放过它。

于是string2再次移动,让另一个Y对齐string1中的Y。看图。

不用说了,再次比较string2的第一位与相应的string1的位。看图。

结果是不相同。同时我这个例子里在string2中已经把所有的Y都比较过了,所以可以继续下面的步骤。如果你的文本里还有尚未比较的Y,还要先逐一比较完。

然后就可以继续跳跃了。找下一位。这时就是string1中的H。

然后又是移动string2。看图吧,图说明得直接点。

好了,已经可以看到很接近了!!但是别激动,计算机还不知道接近了啊。于是按步骤继续比较。看图。

C跟H不一样,于是继续比较string2中左边的H。看图。

终于快完了啊啊啊啊!!!然后计算机对比完成,终于知道找到了。看图。

整个比较的过程就是这样。T T。一直看别人的这么多博客,自己写真的好累。

然后回到开头遗留的问题,我来解释下为什么只比较第一位A和H,还有为什么如果G不在HHYWYQ中,就可以直接跳过七位。

@@首先如果A和H不相等,就只是两串字符的第一位不相等而已。这没什么。但是如果G不在HHYWYQ中,这就意味着从A开始的字母一直到G,与string2绝对不相同,于是可以直接跳过strlen(string2)+1位。

这个我再举个例子吧。

这个是当G存在string2中的情况。

如果不存在,那就是下面的这种情况。

算法实现:

#include<stdio.h>
#include<string.h>
int inthestring2 (char a,char *string2){ // 检查a是否在string2中
    int ct = strlen(string2)-1;
    while(ct >= 0){
        if (string2[ct] == a)
            return (strlen(string2) - ct); //返回a在string2中的位置
        ct--;
    }
    return 0;  //a不在string2中
}
int sunday (char *string1,int len1,char *string2,int len2){
    int j = 0,i = 0,n;
    while(j<=len1){
        i = 0;
        while(string1[i+j] == string2[i])
            i++;
        if (i == len2)
            return i+j-len2+1;//返回string2在string1中的位置
        if( (n=inthestring2(string1[j + len2],string2)) != 0)
            j += n;
        else
            j += (len2 +1);
    }
    return 0;//如果在string1中没有找到string2,则返回0
}
int main()
{
    char *string1,*string2;
    string1 = "ABCDEFYHIJKHHYWYQXYZWQWQW";
    string2 = "HHYWYQ";
/*  string1 = "ABCDEFGHIJKLMNOPQ";
    string2 = "XYZ";*/

    int len1 = strlen(string1),len2 = strlen(string2);
    int n;
    n = sunday(string1,len1,string2,len2);
    printf("位置为:n = %d。\n",n);
    return 0;
}

我的代码是可以用的,可以复制然后自己再运行一遍。代码里一共有两组可供测试的数据,第二组放在注释里的是不匹配的情况,即在string1里是找不到string2的,运行的结果是可以返回0。

。。。。终于完了。可能有些地方还是不太详尽,欢迎提出疑虑和修改建议。

时间: 2024-10-20 22:03:17

字符串匹配:sunday算法的实现。的相关文章

字符串匹配sunday算法c++实现(转)

转载于http://blog.csdn.net/eqmcc/article/details/8205249 sunday.h #include <cstdlib> #include <string> #include <iostream> #include <map> #ifndef _SUNDAYDLL_H_ #define _SUNDAYDLL_H_ using namespace std; class Sunday{ public: Sunday(st

字符串匹配-sunday算法

#include<iostream> using namespace std; //匹配字符串.能匹配子串在原始字符串中所有出现的位置的开始下标,下标以0开始. int match(int i, int n, const char *ori, const char *sub) {  int j;  for (j = 0; j < n; j++)  {   if (ori[i] == sub[j])   {    if (j == n - 1)    {     cout <<

字符串匹配——Sunday算法(C++)

源代码: #include<iostream>#include<cstdio>#include<string>using namespace std;string s1,s2;int m,n,k(0);bool t(0);int main(){ getline(cin,s1); getline(cin,s2); m=s1.size(); n=s2.size(); //C++字符串函数还有待学习. while (!t) { t=true; for (int a=k;a&l

字符串匹配(BF,BM,Sunday,KMP算法解析)

字符串匹配一直是计算机领域热门的研究问题之一,多种算法层出不穷.字符串匹配算法有着很强的实用价值,应用于信息搜索,拼写检查,生物信息学等多个领域. 今天介绍几种比较有名的算法: 1. BF 2. BM 3. Sunday 4. KMP -,BF算法 BF(Brute Force)算法又称为暴力匹配算法,是普通模式匹配算法. 其算法思想很简单,从主串S的第pos个字符开始,和模式串T的第一个字符进行比较,若相等,则主串和模式串都后移一个字符继续比较:若不相同,则回溯到主串S的第pos+1个字符重新

字符串匹配常见算法(BF,RK,KMP,BM,Sunday)

今日了解了一下字符串匹配的各种方法. 并对sundaysearch算法实现并且单元. 字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目.此算法通常输入为原字符串(string)和子串(pattern),要求返回子串在原字符串中首次出现的位置.比如原字符串为"ABCDEFG",子串为"DEF",则算法返回3.常见的算法包括:BF(Brute Force,暴力检索).RK(Robin-Karp,哈希检索).KMP(教科书上最常见算法).BM(

字符串匹配与KMP算法笔记

>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个一个进行比较, 如果不成功则模式串向右移动一个单位,直到匹配成功或者到达匹配串最后仍然不成功,返回失败. 很明显,这种算法有很多的地方可以优化,假设要搜索的串为S,长度为n,要匹配的串为M,长度为m,时间复杂度为O(nm). >>KMP算法 Knuth-Morris-Pratt算法以三个发明者命名

通用固定长度编码格式的字符串查找算法的实现

通用固定长度编码格式的字符串查找算法的实现 字符串的查找是数据库应用中必不可少的操作,而且每种数据库产品(ORACLE.DB2.SYBASE.MS SQL SERVER.MYSQL等等)也都提供了对应的字符串处理函数,比如DB2的LOCATE函数. 但在实际的工作中,还是会遇到一些特殊情况的处理,这使得直接使用字符串查找函数,得到的结果可能是错误的,比如本文中提到的固定长度编码格式的字符串的查找.值得注意的是,本文提出的算法可以稍加修改即移植到其它关系数据库系统或者前端开发工具中. 在实际数据库

KMP字符串匹配

1 #include<iostream> 2 3 4 using namespace std; 5 6 #define MAX 255 7 8 typedef unsigned char BYTE; 9 10 typedef BYTE String[MAX+1]; 11 12 bool strAssign(String& strTemp,char* Temp); //定长字符串存储 13 bool strTravel(String& strTemp); //打印 14 void

[算法系列之十四]字符串匹配之Morris-Pratt字符串搜索算法

前言 我们前面已经看到,蛮力字符串匹配算法和Rabin-Karp字符串匹配算法均非有效算法.不过,为了改进某种算法,首先需要详细理解其基本原理.我们已经知道,暴力字符串匹配的速度缓慢,并已尝试使用Rabin-Karp中的一个散列函数对其进行改进.问题是,Rabin-Karp的复杂度与强力字符串匹配相同,均为O(mn). 我们显然需要采用一种不同方法,但为了提出这种不同方法,先来看看暴力字符串匹配有什么不妥之处.事实上,再深入地研究一下它的基本原理,就能找到问题的答案了. 在暴力匹配算法中,需要检