• 前端
  • JS
  • CSS
  • HTML
  • Mysql
  • Linux
  • SVN
  • 环境uedbet官网手机版最新
  • uedbet西甲体育投注详解
  • MAC_BOOK
  • 算法
  • 字符串匹配KMP算法
    By skyshappiness Posted 2017-03-30 12:30:47 In

    一、简介:

          KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。


    二、原理:

          字符串: ABCBAACEDCBABADB

          搜索串: BABAD


    一、计算搜索串部分匹配表

          ---- B 的前缀和后缀为空                                                         0

          ---- BA 前缀 B 后缀 A    交集为空                                             0

          ---- BAB 前缀 B BA 后缀 AB B交集为 B                                       1

          ---- BABA 前缀 B BA BAB 后缀 ABA BA A  交集为 BA                     2

          ---- BABAD 前缀 B BA BAB BABA 后缀 ABAD BAD AD D 交集为空     0


    二、匹配计算

          1、ABCBAACEDCBABADB

                BABAD

           2、ABCBAACEDCBABADB

                   BABAD                                           位移步数 = 已匹配字符数 - 对应匹配字符数 = 1 - 0 = 1

           3、ABCBAACEDCBABADB

                     BABAD 

           4、ABCBAACEDCBABADB

                       BABAD                                        位移步数 = 已匹配字符数 - 对应匹配字符数 = 2 - 0 = 2

           5、ABCBAACEDCBABADB

                            BABAD                                  此处一直后移一位,直至情况 6 出现

           6、ABCBAACEDCBABADB

                                       BABAD                            


    三、程序语言:

        public function testKMP(){
            $be_search_str = 'ABCBAACEDCBABADB';
            $search_str = 'CBAA';
            $match_table = $this->_calculateMatchTable($search_str);
            $be_search_len = strlen($be_search_str);
            $search_len = strlen($search_str);
            for($i = 0; $i < $be_search_len; $i++){
                $j = 0;
                for($j = 0; $j < $search_len; $j++){
                    $first_compare_word = substr($be_search_str, ($i+$j), 1);
                    $compare_word = substr($search_str, $j, 1);
                    if($first_compare_word === $compare_word){
                        if($j === ($search_len - 1) ){ echo ($i); exit; }
                        $step_value = $j - $match_table[($j-1)];
                    }else{
                        if($step_value > 0){
                            $i = $i + $step_value;
                            $step_value = 0;
                        }
                        break;
                    }
                }
            }
        }
        
        /**
         * 计算部分匹配表
         * @param type $search_str
         * @return boolean|int
         */
        private function _calculateMatchTable($search_str = ''){
            if($search_str == ''){ return FALSE; }
            $result = array();
            $result[] = 0;
            $str_len = strlen($search_str);
            if($str_len == 1){ return $result; }
            for($i = 2; $i <= $str_len; $i++){
                $calculate_str = substr($search_str, 0, $i);
                $calculate_count = 0;
                for($j = 1; $j < $i; $j++){
                    $front_str = substr($search_str, 0, $j);
                    $end_str = substr($search_str, (strlen($calculate_str) - $j), $j);
                    if($front_str === $end_str){
                        $calculate_count += strlen($front_str);
                    }
                }
                $result[] = $calculate_count;
            }
            return $result;
        }

    友情链接
    联系方式
  • 邮箱 / E-mail:121388038@qq.com