简单高效的字符串匹配算法

文章介绍了QuickSearch和Horspool两种简化版的Boyer-Moore字符串匹配算法,它们主要利用坏字符规则提高搜索效率。QuickSearch从前往后匹配,而Horspool从后往前。两种算法都需要预处理步骤来构建辅助数组,以确定模式串的移动位置。它们的时间复杂度为O(n),在特定场景下能提供高效的字符串查找性能。
摘要由CSDN通过智能技术生成

Quick Search算法

算法简介

Quick Search算法属于Sunday算法的一种。Sunday算法由Daniel M Sunday在1990年提出。论文原文:A VERV FAST SU6STRINC SEARCH ALGORITHM

在论文中,作者提出了三个不同的算法:Quick Search算法、Maximal Shift算法以及Optimal Mismatch算法。作者证明了这三种算法效率均优于Boyer-Moore算法。其中,Optimal Mismatch略微好于前两者。但在原理及应用上,Quick Search最为简单。

Quick Search可以被视为一种简化的Boyer-Moore算法。该算法仅使用Boyer-Moore中的“坏字符”规则。此外,与Boyer-Moore算法不同,Quick Search在匹配字符串时是按从头到尾的顺序匹配的。

在下面的描述中,字符串s为目标串(主串、被匹配串),长度为n;字符串p被称为模式串(子串、匹配串),长度为m。

算法步骤

首先将字符串s与p头部对齐,开始以下步骤:

  1. 从p的头部至尾部开始逐一与s匹配

  2. 若匹配成功返回对应位置。若匹配失败,则聚焦到s与p匹配范围外的第一个字符c(图中绿色框)。

  3. 向右移动p,令p中最后一个c与s中的c对齐,如果p中不存在c,则将整个p向后移动m+1位。回到步骤1,重复步骤1、2、3。

请添加图片描述

以上匹配操作的时间复杂度为 O ( n ) O(n) O(n)。为了对任意一个字符c,我们都能快速定位到其在p中最后出现的位置,在执行以上匹配之前需要进行预处理:

基于字符串p构造一个数组a,数组长度等于字符串中所有可能出现的字符数(一般为256),字符对应的数组元素为该字符在p中最后出现的位置与字符串末端的距离+1,举个例子,字符串p为“abc”,则a[‘a’] = 3, a[‘b’] = 2, a[‘c’] = 1。其他未出现的字符对应的数组元素则统一赋值为p的长度+1。预处理操作的时间复杂度为 O ( m ) O(m) O(m)

在匹配过程中,对于s中的任意一个字符c,通过a[c]即可得到p向后移动的位数。

代码
#define ALLCHAR 256

int QuickSearch(char* s, char *p) {
    int n = strlen(s), m = strlen(p);
    int a[ALLCHAR];
    for (int i=0; i<ALLCHAR; ++i)   //初始化数组a
        a[i] = m + 1;
    for (int i=0; i<m; ++i)         //预处理
        a[p[i]] = m - i; 
    
    int now = 0;
    while (now <= n - m) {
        if (memcmp(p, s + now, m) == 0)
            return now;
        now += a[s[now + m]];            
    }

    return -1;
}



Horspool算法

算法简介

Horspool同样是简化版的Boyer-Moore算法。该算法仅使用“坏字符”规则,字符串匹配时与Boyer-Moore算法一样,按从尾到头的顺序。

算法步骤

首先将字符串s与p头部对齐,开始以下步骤:

  1. 从p的尾部至头部开始逐一与s匹配

  2. 若匹配成功返回对应位置。若匹配失败,则聚焦到s与p匹配范围内的最后一个字符c(图中绿色框)。
    请添加图片描述

  3. 向右移动p,令p中除最后一位外最后出现的c与s中的c对齐,如果p中不存在c,则将整个p向后移动m位。回到步骤1,重复步骤1、2、3。

同理,在执行以上匹配操作前需要预处理:基于字符串p构造一个数组a,数组长度等于字符串中所有可能出现的字符数(一般为256),字符对应的数组元素为该字符在p中除最后一位外,最后出现的位置与字符串末端的距离,举个例子,字符串p为“abc”,则a[‘a’] = 2, a[‘b’] = 1, a[‘c’] = m = 3。其他未出现的字符对应的数组元素则统一赋值为p的长度。

代码
#define ALLCHAR 256

int Horspool(char *s, char *p) {
    int n = strlen(s), m = strlen(p);
    int a[ALLCHAR];
    
    for (int i=0; i<ALLCHAR; ++i)
        a[i] = m;
    for (int i=0; i<m-1; ++i)
        a[p[i]] = m-i-1;

    int now = 0;
    while (now <= n-m) {
        if (p[m-1]==s[now+m-1] && memcmp(p, s+now, m-1)==0)
            return now;
        now += a[s[now+m-1]];
    }
    return -1;
}



参考资料

EXACT STRING MATCHING ALGORITHMS

Quick Search algorithm

A VERV FAST SU6STRINC SEARCH ALGORITHM

Horspool algorithm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值