自己做的网站被封了,帝国cms网站地址,价格,上海网络做网站公司为什么要学习这个算法 前一段时间遇到了瓶颈#xff0c;因为词库太多了导致会有一些速度过慢#xff0c;而且一个正则表达式已经放不下了#xff0c;需要进行拆分正则才可以。
正好我以前看过有关 dfa 的介绍#xff0c;但是并没有深入的进行研究#xff0c;所以就趁着周…为什么要学习这个算法 前一段时间遇到了瓶颈因为词库太多了导致会有一些速度过慢而且一个正则表达式已经放不下了需要进行拆分正则才可以。
正好我以前看过有关 dfa 的介绍但是并没有深入的进行研究所以就趁着周末好好的了解一下这个东西。跟 php 的正则进行一下对比看看速度如何如果表现较好说不定还能用得上。
什么是 dfa
通过百度可以知道 dfa 是 确定有穷自动机 的缩写。 应该还会见到类似下面图的说明 原谅我实在一些我这人数学不好不说貌似看图能力也不行这个图恕我直言我没看懂。所以关于精准的解释请大家去百度或者 google 自行查阅了。
我的理解
说明之前我们先看看做检测需要准备的东西
一个组织好的关键词树待检测的字符串
什么是组织好的关键词树
我们一批需要检测词库比如下面这些
日本人日本鬼子日本人傻破解*版 先做个解释前三个大家都能看懂那么 * 是什么这个是我定义的通配符代表着 * 可以是 0 - n 个占位符用来替代在关键词中间插入混淆字符。至于可以替换几个我们可以在代码中进行定义需要注意 n 越大速度就会越慢。
说明完了来看看构造好的树是什么一样的应该是跟下图差不多的。 为什么要手动画一个因为需要对比我的理解跟程序是否一致如果不一致就要找出程序是不是写的不对了。那么我们来看看程序生成的是啥样的。 程序生成的跟图片一致到这里还都是正确的。
待检测的字符串
这个就很容易理解了就是我们需要检测的字符串。
为什么要组织好那样的一棵树算法思路
这块需要先说一个概念
它是是通过event和当前的state得到下一个state即eventstatenextstate 这句话或者类似的话你会在绝大多数的解释文章里面看到。而我的理解就是一个字符一个字符的检测如果检测的字符在我们的树种就进入命中的树看下一个字在不在树里面如果持续的命中就持续进入最后完全命中了也就是那个字的子树只有一个元素并且元素的键是 end 这里是在我们的这个例子中看图就明白了。就是完全命中了关键词就可以记录命中或者准备替换了。
这里说一个可以优化的点看我们的例子有两个词 日本人日本鬼子 这两个如果为了快完全可以去掉第二个词质保流一个就行了这样当检测到 end 就可以直接屏蔽或者记录了而在我们的例子中还需要判断元素数量不是 1 的情况下还得继续深入看看是不是命中了长尾。
这样的长尾检测会引发一个问题那就是 回滚当我们命中了前置的词后续的没有命中的时候就得记录并且回滚这个回滚的长度是是多少呢其实不仅仅是没有命中长尾的回滚还有一个 回滚 操作就是检测率几个字之后就没命中率额就得回顾这个回滚的长度是已检测字符长度 - 1 的长度 。那么没有命中长尾的长度我们就知道了已检测字符长度 - 上次命中的长度 就可以了。
下面我们来看看代码实现。
// 通配符的数量
$maskMin 0;
$maskMax 3;
// 关键词词典字符串这个部分的处理自己可以替换
$dict 傻瓜;
$checkDfaTree [];
$dictArr explode(,, $dict);
// 重组一下带有 * 通配符的数组
$fullDictArr [];
foreach ($dictArr as $word) {if (mb_strpos($word, *) ! false) {// 带有通配符就把通配符去掉for ($maskIndex $maskMin; $maskIndex $maskMax; $maskIndex) {$maskString str_pad(, $maskIndex, *);$inputWord str_replace(*, $maskString, $word);$fullDictArr[] $inputWord;}} else {$fullDictArr[] $word;}
}foreach ($fullDictArr as $word) {// 每次开始新词都要回到树的根部$treeStart $checkDfaTree;$wordLen mb_strlen($word);for ($i 0; $i $wordLen; $i) {$char mb_substr($word, $i, 1);$treeStart[$char] isset($treeStart[$char]) ? $treeStart[$char] : [];if ($i 1 $wordLen) {// 如果已经是次的结尾了就设置null$treeStart[$char][end] true;}// 移动指针到下一个$treeStart $treeStart[$char];}
}
// 遍历str
$start microtime(true);
$checkMessageLen mb_strlen($checkMessage);
$wordArr [];
$checkTreeStart $checkDfaTree;
$hasPrefixLength 0;
$targetWord ;for ($i 0; $i $checkMessageLen; $i) {// 获取一个字符$char mb_substr($checkMessage, $i, 1);if (isset($checkTreeStart[$char])) {// 如果有这个字就进入子树里面if (isset($checkTreeStart[$char][end]) $checkTreeStart[$char][end] true) {// 如果包含这个标识就记录标识$hasPrefixLength mb_strlen($targetWord);}$checkTreeStart $checkTreeStart[$char];$targetWord . $char;} else if (isset($checkTreeStart[*])) {// 如果有通配符就进入子树$checkTreeStart $checkTreeStart[*];$targetWord . $char;} else {if ($hasPrefixLength) {$wordArr[] mb_substr($targetWord, 0, $hasPrefixLength 1);// 回滚$i - mb_strlen($targetWord) - $hasPrefixLength;} else {// 回滚$i - mb_strlen($targetWord);}// 回到头部$checkTreeStart $checkDfaTree;$targetWord ;$hasPrefixLength 0;}if (count($checkTreeStart) 1 isset($checkTreeStart[end]) $checkTreeStart[end] true) {// 子树只有一个并且是end 就说明是命中了// 赋值$wordArr[] $targetWord;// 清空$targetWord ;// 回到头部$checkTreeStart $checkDfaTree;$hasPrefixLength 0;}
}
var_dump($wordArr);
echo br / useTime: . (microtime(true) - $start) * 1000;下面这个就是匹配加测试了目前我能想到的都测试通过了如果有问题可以回复我。
结论
目前来看效率是比正则要好一些命中的情况下速度差不多没命中的情况下表现要优于正则。 文章转载自: http://www.morning.homayy.com.gov.cn.homayy.com http://www.morning.rdkt.cn.gov.cn.rdkt.cn http://www.morning.nyhtf.cn.gov.cn.nyhtf.cn http://www.morning.rwfj.cn.gov.cn.rwfj.cn http://www.morning.qzsmz.cn.gov.cn.qzsmz.cn http://www.morning.wscfl.cn.gov.cn.wscfl.cn http://www.morning.qnftc.cn.gov.cn.qnftc.cn http://www.morning.rpljf.cn.gov.cn.rpljf.cn http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.ynwdk.cn.gov.cn.ynwdk.cn http://www.morning.pqkyx.cn.gov.cn.pqkyx.cn http://www.morning.nbsbn.cn.gov.cn.nbsbn.cn http://www.morning.cwgfq.cn.gov.cn.cwgfq.cn http://www.morning.myzfz.com.gov.cn.myzfz.com http://www.morning.glxdk.cn.gov.cn.glxdk.cn http://www.morning.wbxtx.cn.gov.cn.wbxtx.cn http://www.morning.vehna.com.gov.cn.vehna.com http://www.morning.qwmdx.cn.gov.cn.qwmdx.cn http://www.morning.hcrxn.cn.gov.cn.hcrxn.cn http://www.morning.pqsys.cn.gov.cn.pqsys.cn http://www.morning.rntby.cn.gov.cn.rntby.cn http://www.morning.tfrmx.cn.gov.cn.tfrmx.cn http://www.morning.lhjmq.cn.gov.cn.lhjmq.cn http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.npbnc.cn.gov.cn.npbnc.cn http://www.morning.shnqh.cn.gov.cn.shnqh.cn http://www.morning.pqqzd.cn.gov.cn.pqqzd.cn http://www.morning.wcghr.cn.gov.cn.wcghr.cn http://www.morning.gbnsq.cn.gov.cn.gbnsq.cn http://www.morning.dbjyb.cn.gov.cn.dbjyb.cn http://www.morning.rbbzn.cn.gov.cn.rbbzn.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.gqdsm.cn.gov.cn.gqdsm.cn http://www.morning.ggcjf.cn.gov.cn.ggcjf.cn http://www.morning.zkqsc.cn.gov.cn.zkqsc.cn http://www.morning.txysr.cn.gov.cn.txysr.cn http://www.morning.paxkhqq.cn.gov.cn.paxkhqq.cn http://www.morning.pznqt.cn.gov.cn.pznqt.cn http://www.morning.mywnk.cn.gov.cn.mywnk.cn http://www.morning.wrdlf.cn.gov.cn.wrdlf.cn http://www.morning.lthtp.cn.gov.cn.lthtp.cn http://www.morning.cniedu.com.gov.cn.cniedu.com http://www.morning.krlsz.cn.gov.cn.krlsz.cn http://www.morning.gnlyq.cn.gov.cn.gnlyq.cn http://www.morning.npmx.cn.gov.cn.npmx.cn http://www.morning.pwksz.cn.gov.cn.pwksz.cn http://www.morning.rjnx.cn.gov.cn.rjnx.cn http://www.morning.qggcc.cn.gov.cn.qggcc.cn http://www.morning.zmpsl.cn.gov.cn.zmpsl.cn http://www.morning.plfy.cn.gov.cn.plfy.cn http://www.morning.fdmtr.cn.gov.cn.fdmtr.cn http://www.morning.bpmtj.cn.gov.cn.bpmtj.cn http://www.morning.nnhfz.cn.gov.cn.nnhfz.cn http://www.morning.tkhyk.cn.gov.cn.tkhyk.cn http://www.morning.dpflt.cn.gov.cn.dpflt.cn http://www.morning.yqndr.cn.gov.cn.yqndr.cn http://www.morning.hlxpz.cn.gov.cn.hlxpz.cn http://www.morning.lgpzq.cn.gov.cn.lgpzq.cn http://www.morning.xmttd.cn.gov.cn.xmttd.cn http://www.morning.zmnyj.cn.gov.cn.zmnyj.cn http://www.morning.pqrhb.cn.gov.cn.pqrhb.cn http://www.morning.mlcnh.cn.gov.cn.mlcnh.cn http://www.morning.wjhqd.cn.gov.cn.wjhqd.cn http://www.morning.dzdtj.cn.gov.cn.dzdtj.cn http://www.morning.bfrsr.cn.gov.cn.bfrsr.cn http://www.morning.yhywx.cn.gov.cn.yhywx.cn http://www.morning.rjhts.cn.gov.cn.rjhts.cn http://www.morning.jtszm.cn.gov.cn.jtszm.cn http://www.morning.ttryd.cn.gov.cn.ttryd.cn http://www.morning.bkfdf.cn.gov.cn.bkfdf.cn http://www.morning.pnmtk.cn.gov.cn.pnmtk.cn http://www.morning.zwmjq.cn.gov.cn.zwmjq.cn http://www.morning.jcxgr.cn.gov.cn.jcxgr.cn http://www.morning.qxmpp.cn.gov.cn.qxmpp.cn http://www.morning.ktcfl.cn.gov.cn.ktcfl.cn http://www.morning.c7625.cn.gov.cn.c7625.cn http://www.morning.hpnhl.cn.gov.cn.hpnhl.cn http://www.morning.gthc.cn.gov.cn.gthc.cn http://www.morning.mrfgy.cn.gov.cn.mrfgy.cn http://www.morning.pdmml.cn.gov.cn.pdmml.cn