3.Sunday算法的一个小优化
优化算法思路:
1.Sunday算法关键思想
通过解析传统Sunday算法我发现它实现跳转的关键思想在于第二步,我们深入解析下第二步的原理:
we should working hard
work
h为什么要和work中的元素逐个比较?我们可以这样理解:
1) 当h和w比较时,我们可以确定houl和work是否可能匹配
2) 当h和o比较时,我们可以确定shou和work是否可能匹配
3) 当h和r比较时,我们可以确定 sho和work是否可能匹配
4) 当h和k比较时,我们可以确定e sh和work是否可能匹配
也就是说,这次比较我们可以确定e shoul和work的关系。
we should working hard
work
那么我们的优化策略就有了:
当h和work经过比较后发现h不在work中,我们可以直接跳过oul,用d来重复h的操作,以此类推,直到找到匹配项。
改进后的Sunday算法:
我们假设有一个字符串A长度为n 一个字符串B长度为m
我们使用Sunday算法在A中查找是否存在B
我们假设每次比较的时间为1,本文的复杂度分析主要是最坏复杂度分析
1) 将A,B首字母对齐
2) 查看B最后一个字符对应的A的位置(初始为m)上的字符是否在B中存在m次比较
3) 若存在,则将B中对应位置与其对齐后倒序比较,若全部相等则找到目标,否则执行步骤4 m-1次比较
4) 若不存在则将检查m+m位置上的字符是否在B中存在。m次比较
图示过程:
w e s h o u l d w o r k i n g h a r d
w o r k
1)首先查看s是否在work中存在,结果为不存在,跳过4位到l上
2)检查l在work中是否存在,结果为不存在,跳过4位到o上
3)检查o在work中是否存在,发现存在,则将两个串中的o对齐得到下面的:
w e s h o u l d w o r k i n g h a r d
w o r k
4)检查它们相对应的串是否匹配,结果发现匹配,得到结果,配对完毕。
复杂度分析
我们拿传统Sunday算法的最坏复杂度情况进行计算:
类似下面情况的查找的复杂度最坏:
wordkkkkkkkkkkkkkkkkkkk
work
通过计算这样的复杂度为:
O(n,m)=(2m-1)n/m
化简后就是:O(n,m)=2n-n/m
我们知道当n远大于m的时候,其时间复杂度可以近似看成:O(n)=n
这与传统的Sunday相比近似快了一倍。
代码实现
public int Sunday(String haystack, String needle) {
int hayLen = haystack.length();//主串长度
int nLen = needle.length();//子串长度

浙公网安备 33010602011771号