设为首页 收藏本站
查看: 735|回复: 0

[经验分享] PHP 字符串匹配算法 Sunday算法

[复制链接]
累计签到:5 天
连续签到:1 天
发表于 2015-8-30 11:50:29 | 显示全部楼层 |阅读模式
  搜索文本 text = "my testing algorithm in test"
  模式 pattern = "test"
  Sunday算法的关键点在于
  1.设定一个匹配位移映射 shift[],这个shift[]映射关系必须按从左到右的顺序简历,例如pattern = "test",注意到此处有2个t,那么建立出来的位移映射是 shift[] = Array ( [t] => 1 [e] => 3 => 2 ),而如果不是从左到右,是从右到左的建立映射,就会变成 shift[] = Array ( [t] => 4 [e] => 3 => 2),这样到时候匹配就无法得到正确结果
  2.根据当前比对字符串的下一个字符来确定位移长度,如下图
DSC0000.jpg
  第一次比较的时候,如图1,第一个字符“m”就和“t”不一样,那就查找比patter长1位的text中的字符,为“e”,然后查找映射表,e => 3,接下来把pattern向后移动3位,就到了,图2中的位置,再从“t”开始比较,发现匹配到了继续往后,看text中比pattern长1的那个字符,为“i”,此时发现映射表中没有“i”,则直接将pattern向后移动pattern_size位,就到了图3,然后重复前面的过程,直到比较到text_size - patter_size为坐标的那个字符
  
  下面是代码:



1 <?php
2     #字符串匹配,sunday算法
3     
4     function sunday($patt, $text) {
5         $patt_size = strlen($patt);
6         $text_size = strlen($text);
7
8         #初始化字符串位移映射关系
9         #此处注意,映射关系表的建立一定是从左到右,因为patten可能存在相同的字符
10         #对于重复字符的位移长度,我们只能让最后一个重复字符的位移长度覆盖前面的位移长度
11         #例如pattern = "testing",注意到此处有2个t,那么建立出来的位移映射是 shift[] = Array ( [t] => 4 [e] => 6 => 5 => 3 [n] => 2 [g] => 1 )
12         #而如果不是从左到右,是从右到左的建立映射,就会变成 shift[] = Array ( [t] => 7 [e] => 6 => 5 => 3 [n] => 2 [g] => 1 ),这样到时候匹配就无法得到正确结果
13         for ($i = 0; $i < $patt_size; $i++) {
14             $shift[$patt[$i]] = $patt_size - $i;
15         }
16
17         $i = 0;
18         $limit = $text_size - $patt_size; #需要开始匹配的最后一个字符坐标
19         while ($i <= $limit) {
20             $match_size = 0; #当前已匹配到的字符个数
21             #从i开始匹配字符串
22             while ($text[$i + $match_size] == $patt[$match_size]) {
23                 $match_size++;
24                 if ($match_size == $patt_size) {
25                     echo "Match index: {$i} <br>";
26                     break;
27                 }
28             }
29
30             $shift_index = $i + $patt_size; #在text中比pattern的多一位的字符坐标
31             if ($shift_index < $text_size && isset($shift[$text[$shift_index]])) {
32                 $i += $shift[$text[$shift_index]];
33             } else {
34                 #如果映射表中没有这个字符的位移量,直接向后移动patt_size个单位
35                 $i += $patt_size;
36             }
37         }
38     }
39
40     $text = "my testing algorithm test";
41     $patt = "test";
42
43     sunday($patt, $text);
44 ?>
  
  

  Match index: 3
Match index: 21


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106291-1-1.html 上篇帖子: (转)smarty里使用php函数 下篇帖子: php使用iconv进行从utf-8转为gb2312字符编码出错解决方案
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表