Loading

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)=2
n-n/m
我们知道当n远大于m的时候,其时间复杂度可以近似看成:O(n)=n

这与传统的Sunday相比近似快了一倍。

代码实现

public int Sunday(String haystack, String needle) {
   
        int hayLen = haystack.length();//主串长度
        int nLen = needle.length();//子串长度
        
posted @ 2020-06-26 15:13  文牧之  阅读(39)  评论(0)    收藏  举报  来源