天马阁

 找回密码
 立即注册
                                        →→→→→→→→→→→→ 1点击查看所有VIP教程目录长列表(总教程数269个) 2办理VIP详情进入 ←←←←←←←←←←←←
1 x64CE与x64dbg入门基础教程 7课 已完结 2 x64汇编语言基础教程 16课 已完结 3 x64辅助入门基础教程 9课 已完结 4 C++x64内存辅助实战技术教程 149课 已完结
5 C++x64内存检测与过检测技术教程 10课 已完结 6 C+x64二叉树分析遍历与LUA自动登陆教程 19课已完结 7 C++BT功能原理与x64实战教程 29课 已完结 8 C+FPS框透视与自瞄x64实现原理及防护思路 30课完结
64驱?封? 9 64反驱? 10 64位V? 11 绝? 12 ???课?
13 64透 ? 14 64U ? 15 64Q ? 16 64功 ?
17 64U ? 18 64模 ? 19 64多 ? 20 64网 ?
21 64注 ? 22 64火 ? 23 64棋 ? 24 64自二链L?
25 64破 ? VIP会员办理QQ: 89986068   
【请先加好友,然后到好友列表双击联系客服办理,不然可能无法接受到信息。】
27 加入2000人交流群637034024 3 28 免责声明?
查看: 4324|回复: 0

Sunday算法原理与实现(模式匹配)

[复制链接]

12

主题

1

回帖

15

积分

编程入门

Rank: 1

天马币
24
发表于 2024-3-6 09:25:35 | 显示全部楼层 |阅读模式
字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore)。两个算法在最坏情况下均具有线性的查找时间。但是在实用上,KMP算法并不比最简单的c库函数strstr()快多少,而BM算法则往往比KMP算法快上3-5倍。但是BM算法还不是最快的算法,这里介绍一种比BM算法更快一些的查找算法---Sunday算法。

   Sunday算法其实思想跟BM算法很相似,只不过Sunday算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。如果该字符没有在匹配串中出现则直接跳过,即移动步长= 匹配串长度+ 1;否则,同BM算法一样其移动步长=匹配串中最右端的该字符到末尾的距离+1。

具体源代码实现如下(源代码中已注明实现过程):

#include<iostream>
#include<string.h>
using namespace std;
//一个字符8位 最大256种
#define MAX_CHAR_SIZE 256
#define MAXSIZE 100
/*
设定每个字符最右移动步长,保存每个字符的移动步长
如果大串中匹配字符的右侧一个字符没在子串中,大串移动步长=整个串的距离+1
如果大串中匹配范围内的右侧一个字符在子串中,大串移动距离=子串长度-这个字符在子串中的位置
*/
int *setCharStep(char *subStr)
{
int i;
     int *charStep=new int[MAX_CHAR_SIZE];
     int subStrLen=strlen(subStr);
     for(i=0;i<MAX_CHAR_SIZE;i++)
             charStep=subStrLen+1;
     //从左向右扫描一遍 保存子串中每个字符所需移动步长
     for(i=0;i<subStrLen;i++)
     {
            charStep[(unsigned char)subStr]=subStrLen-i;        
     }
     return charStep;
}


/*
   算法核心思想,从左向右匹配,遇到不匹配的看大串中匹配范围之外的右侧第一个字符在小串中的最右位置
   根据事先计算好的移动步长移动大串指针,直到匹配
*/
int sundaySearch(char *mainStr,char *subStr,int *charStep)
{
     int mainStrLen=strlen(mainStr);
     int subStrLen=strlen(subStr);
     int main_i=0;
     int sub_j=0;
     while(main_i<mainStrLen)
     {                  
            //保存大串每次开始匹配的起始位置,便于移动指针
             int tem=main_i;
             while(sub_j<subStrLen)
             {
                    if(mainStr[main_i] == subStr[sub_j])
                    {
                            main_i++;
                            sub_j++;
                            continue;                  
                    }               
                    else{
                        //如果匹配范围外已经找不到右侧第一个字符,则匹配失败
                         if(tem+subStrLen > mainStrLen)
                                     return -1;
                         //否则 移动步长 重新匹配
                         char firstRightChar=mainStr[tem+subStrLen];
                         main_i+=charStep[(unsigned char)firstRightChar];
                         sub_j=0;   
                         break;//退出本次失败匹配 重新一轮匹配
                    }  
             }
             if(sub_j == subStrLen)
                       return main_i-subStrLen;
     }
     return -1;
}


int main()
{
char mainStr[MAXSIZE];
char subStr[MAXSIZE];
int answer, i;
printf("\nBoyer-Moore String Searching Program");
printf("\n====================================");
printf("\n\nmainStr String --> ");
gets(mainStr);
printf( "\nsubStr String --> ");
gets(subStr);
int *charStep=setCharStep(subStr);
if ((answer = sundaySearch(mainStr,subStr,charStep)) >= 0)
{
  printf("\n");
  printf("%s\n", mainStr);
  for (i = 0; i < answer; i++)
   printf(" ");
  printf("%s", subStr);
  printf("\n\nPattern Found at location %d\n", answer);
}
else
  printf("\nPattern NOT FOUND.\n");
return 0;
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

天马阁|C/C++辅助教程|安卓逆向安全| 论坛导航|免责申明|Archiver||网站地图
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表天马阁立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2010-2021 All Right Reserved.
快速回复 返回顶部 返回列表