php 字符串英文匹配,字符串匹配算法——Sunday(PHP实现)

Sunday 算法(尽可能的移动最大长度)

Sunday算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符

如果该字符没有在主模式字符串中出现则跳过,移动位 = 匹配字符串长度 + 1

该字符在主模式字符串中出现,

1)移动位 = 该字符在模式串中最后出现位置距末端长度 + 1

2)移动位 = 模式串长度 - 该字符在模式串中最后出现位置

文本串第1个字符 s != 模式串第1个字符 e,那么关注文本串中参加匹配的未位字符下一个字符: a

344b4c6a191b?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weibo

image.png

a 在 ea 字符串的最后一位,则移动位= 0 + 1 = 2(模式串长度) - 1(a 在模式串最后出现位置)= 1

344b4c6a191b?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weibo

image.png

模式串向右移动 1 位,使上下文的 a 对齐

344b4c6a191b?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weibo

image.png

匹配成功

代码现实

namespace Patterns\Algorithm;

/**

* 如果该字符没有在主模式字符串中出现则跳过,移动位 = 匹配字符串长度 + 1

* 该字符在主模式字符串中出现,

1)移动位 = 该字符在模式串中最后出现位置距末端长度 + 1

2)移动位 = 模式串长度 - 该字符在模式串中最后出现位置

* Class Sunday

* @package Patterns\Algorithm

*/

class Sunday

{

public $_needleLen;

public $_haystackLen;

public $_table;

/**

* 返回 -1 表示无法匹配,否则返回首次出现位置

*

* @param string $haystack

* @param string $needle

* @return int

*/

public function strpos(string $haystack, string $needle):int

{

$this->_haystackLen = strlen($haystack);

$this->_needleLen = strlen($needle);

if($this->_needleLen > $this->_haystackLen){

return null;

}

$this->prefixTable($needle);

$p = $this->_haystackLen - $this->_needleLen;

$s = 0;

while ($s <= $p){

$j = 0;

while ($haystack[$s + $j] == $needle[$j]){

$j += 1;

if($j == $this->_needleLen){

return $s;

}

}

$haystackIndex = $s + $this->_needleLen;

if(!isset($haystack[$haystackIndex]))

break;

$hIndexText = $haystack[$haystackIndex];

$s += (isset($this->_table[$hIndexText]) ? $this->_table[$hIndexText] : $this->_needleLen);

}

return -1;

}

/**

* 匹配所有出现位置

* @param string $haystack

* @param string $needle

* @return array

*/

public function strapos(string $haystack, string $needle):array

{

$this->_haystackLen = strlen($haystack);

$this->_needleLen = strlen($needle);

if($this->_needleLen > $this->_haystackLen){

return null;

}

$this->prefixTable($needle);

$p = $this->_haystackLen - $this->_needleLen;

$s = 0;

$pos = [];

while ($s <= $p){

$j = 0;

while (isset($needle[$j]) && $haystack[$s + $j] == $needle[$j]){

$j += 1;

if($j == $this->_needleLen){

array_push($pos, $s);

}

}

$haystackIndex = $s + $this->_needleLen;

if(!isset($haystack[$haystackIndex]))

break;

$hIndexText = $haystack[$haystackIndex];

$s += (isset($this->_table[$hIndexText]) ? $this->_table[$hIndexText] : $this->_needleLen);

}

return $pos;

}

/**

* 模式串字符表

* @param string $needle

*/

public function prefixTable(string $needle)

{

for($i=0; $i < $this->_needleLen; $i++){

//字符最后出现的位置距末端长度:字符串长度 - 字符当前位置

$this->_table[$needle[$i]] = $this->_needleLen - $i;

}

}

}

$haystack = 'search title.';

$needle = 'w';

$obj = new Sunday();

$index = $obj->strpos($haystack, $needle);

echo $index . PHP_EOL;

var_export($obj->strapos($haystack, $needle));

echo strpos($haystack, $needle) . PHP_EOL;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值