Perl KMP 算法
来源:互联网 发布:云杉网络 ceo 编辑:程序博客网 时间:2024/06/07 04:36
了解了一下KMP 算法,自己尝试实现,也比较简单,具体原理参考google baidu,不再重复,这里只作为一个学习的纪录。
use Data::Dumper;my $from = 'abababd ababc';my $find = 'ababc';# 分隔字符串为arraymy @from = split '', $from;my @find = split '', $find;print $find, "\n";print @{ calc( \@find ) }, "\n";print "\n";print kmp( \@from, \@find );############################# 计算字符串的重复值sub calc { my ($array) = @_; # 取与字串相同长度的array 并将第一个置0 my @tmp = (@$array); $tmp[0] = 0;# 之后的每一个字符都与开头字串比较,取@tmp 前一个值作为比较字符# 若为0,前一字符个与开头不重复,比较字符指向开头0# 若不为0,前一个字符与开头有重复,如果还相同,@tmp 值加1,否则为0,后继自符重新从头开始比较 for ( 1 .. $#tmp ) { if ( $array->[$_] eq $array->[ $tmp[ $_ - 1 ] ] ) { $tmp[$_] = $tmp[ $_ - 1 ] + 1; } else { $tmp[$_] = 0; } } return \@tmp;}sub kmp { my ( $from, $find ) = @_; # 初始从开头比较 my $i = 0; my $tmp = calc($find); # 剩余字串长度小于搜索字串,则退出返回-1 while ( ( $#{$from} - $i ) >= $#{$find} ) { # 观察每次步进长度 print @$from[ $i .. $#{$from} ], "\n"; # j 标记搜索到的字串长度 my $j = 0; while ( $find->[$j] eq $from->[ $i + $j ] ) { # 搜索到的长度与字符串长度相同,说明找到,返回index位置 if ( $j == $#{$find} ) { return $i; } else { $j++; } } # 有相同的字符串,根据计算的值来跳转多个字符并重新比较 # $j 为相同的个数(以1为基数),@tmp[$j-1] 为同开始字符重复的个数 if ($j) { $i += $j - $tmp->[ $j - 1 ]; } else { $i++; } } return -1;}输出:
#字符串以及计算重复值结果ababc00120#每次查找过程abababd ababcababd ababcabd ababcd ababc ababcababc8
优化:
由于KMP 搜索过程中已经判断了子字符串的重复性,下一次判断过程中可以根据计算的重复值跳过部分开头字符,直接从不重复的地方开始比较。如下为改进的算法:
sub kmp { my ( $from, $find ) = @_; # 初始从开头比较 my $i = 0; my $tmp = calc($find); my $j = 0; # 剩余字串长度小于搜索字串,则退出返回-1 while ( ( $#{$from} - $i ) >= $#{$find} ) { # 观察每次步进长度 print "$i $j => ", @$from[ $i .. $#{$from} ], "\n"; # j 标记搜索到的字串长度 while ( $j <= $#{$find} && $find->[$j] eq $from->[ $i + $j ] ) { $j++; print ".\n"; # 记录由于$j 的变化自符比较的减少过程,用于debug } # 有相同的字符串,根据计算的值来跳转多个字符并重新比较 # $j 为相同的个数(以1为基数),@tmp[$j-1] 为同开始字符重复的个数 if ( !$j ) { $i += 1; } elsif ( $j <= $#{$find} ) { $i += $j - $tmp->[ $j - 1 ]; $j = $tmp->[ $j - 1 ]; } else { return $i; } } return -1;}
- Perl KMP 算法
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- baidu百科-ioctl
- UML类图图示样例及说明
- 多线程编程10个例子
- 解决网页中插入视频
- QTP 同步点
- Perl KMP 算法
- sip学习二 (一个简单的SIP呼叫建立流程)
- 肾有多好,人就有多年轻。男女通用
- C++人类学生类
- 二维数组作为参数的函数的定义及调用方法
- 一生得失总是零
- 失恋后才发现自己背后的那个人
- 进程、线程、文件共享--操作系统概念--unix环境高级编程
- 蒙迪欧致胜如何进入工程模式查看平均油耗