字符串匹配算法

我们先说下定义,比如说我们要在a字符串中查找字符串b,那么a就是主串,b就是模式串

我们把主串的长度记为n,把模式串的长度记为m,n>m

BF(Brute Force)中文名:暴力匹配算法,朴素匹配算法

简单的说BF的算法就是在主串中查找起始位置是0,1,2,n-m个且长度为m的n-m+1个子串,看看有没有跟模式串匹配的

如下图所示
在这里插入图片描述
下面是我用php实现的BF算法的代码,很简单

function BFString($mainString = ‘abcdefghijklmn’, $patternString = ‘lmn’)
{
//主串长度
n = s t r l e n ( n = strlen( n=strlen(mainString);
//模式串长度
m = s t r l e n ( m = strlen( m=strlen(patternString);
//需要匹配的次数
$needMatchCount = $n - $m + 1;
//真实匹配的次数
$trueMatchCount = 0;
//是否匹配到
i s M a t c h = f a l s e ; f o r ( isMatch = false; for ( isMatch=false;for(i = 0; $i <= $needMatchCount; $i++) {
n o w S t r i n g = s u b s t r ( nowString = substr( nowString=substr(mainString, $i, m ) ; i f ( m); if ( m);if(patternString == $nowString) {
$isMatch = true;
$trueMatchCount = $i;
break;
}
}
return [‘isMatch’ => $isMatch, ‘trueMatchCount’ => $trueMatchCount];
}
这种算法的时间复杂度是O(n*m),可以看出来很暴力,但是实际运用中,这种算法用的还是很多的

原因:

1:实现起来简单,出bug以后容易修复

2:实际软件开发中,主串和模式串的长度都不会很长,而且在匹配中当模式串遇到不能匹配的字符时就停止了,不需要把m个字符都匹配

字符串匹配算法RK(Rabin-Karp)算法

这个算法的核心就是计算出模式串的哈希值,然后依次和主串中每个子串的哈希值进行比较

因为哈希值计算出来的是数字,数字和数字比较速度会比字符串和字符串比较速度快

所以说这个算法就是BF算法的改进版
在这里插入图片描述
实现代码如下

/**

  • 字符串匹配算法RK(Rabin-Karp)算法
    /
    function RKString($mainString, $patternString)
    {
    //主串长度
    n = s t r l e n ( n = strlen( n=strlen(mainString);
    //模式串长度
    m = s t r l e n ( m = strlen( m=strlen(patternString);
    //需要匹配的次数
    $needMatchCount = $n - $m + 1;
    //需要匹配的字符的哈希值
    p a t t e r n S t r i n g H a s h = s e l f : : R K S t r i n g H a s h ( patternStringHash = self::RKStringHash( patternStringHash=self::RKStringHash(patternString);
    //真实匹配的次数
    $trueMatchCount = 0;
    //是否匹配到
    i s M a t c h = f a l s e ; f o r ( isMatch = false; for ( isMatch=false;for(i = 0; $i <= $needMatchCount; $i++) {
    n o w S t r i n g = s u b s t r ( nowString = substr( nowString=substr(mainString, $i, $m);
    n o w S t r i n g H a s h = s e l f : : R K S t r i n g H a s h ( nowStringHash = self::RKStringHash( nowStringHash=self::RKStringHash(nowString);
    //因为哈希算法可能有冲突,所以这里多加了一个$patternString == n o w S t r i n g 判 断 条 件 i f ( nowString判断条件 if ( nowStringif(patternStringHash == $nowStringHash && $patternString == $nowString) {
    $isMatch = true;
    $trueMatchCount = $i;
    break;
    }
    }
    return [‘isMatch’ => $isMatch, ‘trueMatchCount’ => $trueMatchCount, ‘nowString’ => $nowString, ‘nowStringHash’ => $nowStringHash];
    }
    /
    *
  • 字母转成26进制(哈希)
  • @param $num
  • @param int $bin
  • @return float|int
    */
    public static function RKStringHash($string, $bin = 26)
    {
    a r r = s e l f : : B I N T O D E C D A T A ; i f ( arr = self::BIN_TODEC_DATA; if ( arr=self::BINTODECDATA;if(bin == 10) return $string; //为10进制不转换
    a t n u m = s t r s p l i t ( atnum = str_split( atnum=strsplit(string); //将字符串分割为单个字符数组
    a t l e n = c o u n t ( atlen = count( atlen=count(atnum);
    $total = 0;
    i = 1 ; f o r e a c h ( i = 1; foreach ( i=1;foreach(atnum as $tv) {
    t v = s t r t o u p p e r ( tv = strtoupper( tv=strtoupper(tv);
    if (array_key_exists($tv, KaTeX parse error: Expected '}', got 'EOF' at end of input: arr)) { if (arr[$tv] == 0) continue;
    $total = $total + a r r [ arr[ arr[tv] * pow($bin, $atlen - $i);
    }
    $i++;
    }
    return $total;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值