算法设计与分析(清华第二版,王晓东)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析
第 趟
i
i
a b a b c a b c a c b a b
a
jj i
2 3
i=2,j=1失败 i回溯到3,j回溯到1
ii
i i i
第 趟
a b a b c a b c a c b a
a b c a c
jj j j j j
b
i=7,j=5失败 i回溯到4,j回溯到1
清华大学出版社
算法设计与分析
模式应该向右滑多远才是最高效率的?
k=max { k |1<k<j 且T1…Tk-1=Tj-(k-1) …Tj-1 }
清华大学出版社 令k = next[ j ],则: next[ j ]=
算法设计与分析
0 当j=1时 //不比较 max { k | 1<k<j 且T1…Tk-1=Tj-(k-1) …Tj-1 } 1 其他情况
(1)理论上,蛮力法可以解决可计算领域的各种问题。
(2)蛮力法经常用来解决一些较小规模的问题。
(3)对于一些重要的问题蛮力法可以产生一些合理的算 法,他们具备一些实用价值,而且不受问题规模的限制。
(4)蛮力法可以作为某类问题时间性能的底限,来衡量 同样问题的更高效算法。
清华大学出版社
算法设计与分析
动的新比较起点k?
②模式应该向右滑多远才是最高效率的?
清华大学出版社
算法设计与分析
i
请抓住部分匹配时的两个特征:
i
S="a b a b c a b c a c b a b" S="a b a b c a b c a c b a b" T="a b c a c" T="a b c a c"
k j k i
清华大学出版社
算法设计与分析
第3章 蛮力法
3.1 蛮力法的设计思想 3.2 查找问题中的蛮力法
3.3 排序问题中的蛮力法
3.4 组合问题中的蛮力法 3.5 图问题中的蛮力法 3.6 几何问题中的蛮力法 3.7 实验项目——串匹配问题
清华大学出版社
算法设计与分析
3.1 蛮力法的设计思想
蛮力法的设计思想:直接基于问题的描述。
第 趟
i
i
4
a b a b c a b c a c b a
a
jj
i i
b
i=4,j=1失败 i回溯到5,j回溯到1
第 趟
a b a b c a b c a c b a
a
jj
b
5
i=5,j=1失败 i回溯到6,j回溯到1
清华大学出版社
算法设计与分析
第 趟
i
i
i
i i
i
6
a b a b c a b c a c b a b a b c a c
清华大学出版社
算法设计与分析
计算next[j]的方法:
由模式T的前缀函数定义易知,next[1]=0,假设已经 计算出next[1],next[2],…,next[j],如何计算next[j+1] 呢?设k=next[j],这意味着t1 … tk-1既是t1 … tj-1的真后缀又 是t1 … tj-1的真前缀,即: t1 … tk-1=tj-k+1tj-k+2 … tj-1 此时,比较tk和tj,可能出现两种情况: (1)tk=tj:说明t1 … tk-1tk=tj-k+1 … tj-1tj,由前缀函数定义, next[j]=k+1;
∵t1=t5, t1t2t3=t3t4t5 ∴a和aba都是ababa的真前缀和真后缀, 但aba的长度最大 ∴next[6]=3+1=4 即当t6和si匹配失败后,将t4和si进行比较
t1 t2 t3 t4 t5 t6
ababac
真前缀 真后缀
next[j]函数表征着模式T中最大相同首子串和尾子串(真 子串)的长度。可见,模式中相似部分越多,则next[j]函数越 大,模式串向右滑动得越远,与主串进行比较的次数越少,时 间复杂度就越低。
最大真前缀 最大真后缀
t1 … tnext[k]-1 tnext[k] … tk-1 tk … tj-next[k]+1 … tj-1 tj tj+1
最2大真前缀 最2大真后缀
清华大学出版社
算法设计与分析
再比较tnext[k]和tj,此时仍会出现两种情况,当tnext[k]=tj时, 与情况(1)类似,next[j]=next[k]+1;当tnext[k]≠tj时,与情况 (2)类似,再找t1 … tj-1的后缀中第3大真前缀,重复(2) 的过程,直到找到t1 … tj-1的后缀中的最大真前缀,或确定 t1 … tj-1的后缀中不存在真前缀,此时,next[j+1]=1。
清华大学出版社
算法设计与分析
T1…Tk-1=Tj-(k-1) …Tj-1说明了什么? (1) k 与 j 具有函数关系,由当前失配位置 j , 可以计算出滑动位置 k(即比较的新起点); (2)滑动位置k 仅与模式串T有关。
T1…Tk-1=Tj-(k-1) …Tj-1的物理意义是什么?
从第1位往右 经过k-1位 从j-1位往左 经过k-1位
1 n n 1 pici n (n i 1) 2 O(n) i 1 i 1
n
数量级相同, 系数相差一半
清华大学出版社
算法设计与分析
一般观点:
用蛮力法设计的算法,一般来说,经过适度的 努力后,都可以对算法的第一个版本进行一定程度 的改良,改进其时间性能,但只能减少系数,而数 量级不会改变。
基本语句 ?
算法3.1的基本语句是i>0和r[i]!=k,其执行次数为:
1 n 1 n pibi pici n (n i 1) n (n i 1) n 1 O(n) i 1 i 1 i 1 i 1
n
n
清华大学出版社
算法设计与分析
改进的顺序查找
j j j j j j
i=11 , j=6 , t 中 全 部 字符都比较完毕,匹 配成功。
清华大学出版社
算法设计与分析
算 法
int BF(char S[ ], char T[ ]) { i=1; j=1; while (i<=S[0] && j<=T[0] ) { if (S[i]==T[j]) {i++; j++;} else {i=i-j+2; j=1; } } if (j>T[0]) return (i-j+1); else return 0; }
(1)设模式滑动到第k个字符,则T1~Tk-1 =Si-(k-1) ~ Si-1
S="a b a b c a b c a c b a b" T="a b c a c"
k j
(2)则Tj-(k-1) ~ Tj-1 =Si-(k-1) ~ Si-1
两式联立可得:T1~Tk-1=Tj-(k-1) ~Tj-1
(2)算法改进所取得的积累效益不容忽视:串匹配操作 经常被调用,执行频率高。
清华大学出版社
算法设计与分析
蛮力法解决串匹配问题——BF算法
基本思想:从主串S的第一个字符开始和模式T的第一个 字符进行比较,若相等,则继续比较两者的后续字符;若不 相等,则从主串S的第二个字符开始和模式T的第一个字符 进行比较,重复上述过程,若T中的字符全部比较完毕,则 说明本趟匹配成功;若最后一轮匹配的起始位置是n-m,则 主串S中剩下的字符不足够匹配整个模式T,匹配失败。这 个算法称为朴素的模式匹配算法,简称BF算法。
清华大学出版社
算法设计与分析
(2)tk≠tj:此时要找出t1 … tj-1的后缀中第2大真前缀,显然, 这个第2大的真前缀就是next[next[j]]=next[k]。
t1 … tnext[k]-1 tnext[k] … tk-1 tk … tj-next[k]+1 … tj-1 tj tj+1
5 6
s5=t3;t1≠t3 ∴t1≠s5
i
i
i
a b a b c a b c a c b a b
a b c a c
j j j j j
清华大学出版社
算法设计与分析
结论: i可以不回溯,模式向右滑动到的新 比较起点k ,并且k 仅与模式串T有关! 需要讨论两个问题:
①如何由当前部分匹配结果确定模式向右滑
清华大学出版社
算法设计与分析
本趟匹配开始位置 回溯 主串S
i
si
…
模式T
……
tj
回溯
j
清华大学出版社
算法设计与分析
ቤተ መጻሕፍቲ ባይዱ
设主串s=“ababcabcacbab”,模式t=“abcac
i ii i
第 趟
a b
a
jj
a
c
j
b c a
b c
a
c b
a
b
1
b
j
i=3,j=3失败; i回溯到2,j回溯到1
清华大学出版社
清华大学出版社
算法设计与分析
i
i
i
第 趟
a a
j
b b
j
a c
j
b c a
b c a
c b
a
b
第 趟
1 2
i=3,j=3失败;
i
a
b a
j
a
b
c a
b
c a
c b
a
b
s2=t2;t1≠t2 ∴t1≠s2
清华大学出版社 i
算法设计与分析
i
i i
i
第 趟
a b a b c a b c a c b a
3.2 查找问题中的蛮力法
3.2.1 顺序查找
3.2.2 串匹配问题
清华大学出版社
算法设计与分析
3.2.1 顺序查找
顺序查找从表的一端向另一端逐个将元素与给定值进行 比较,若相等,则查找成功,给出该元素在表中的位置;若 整个表检测完仍未找到与给定值相等的元素,则查找失败, 给出失败信息。
0 1 2 3 24 4 5 6 7 8 9 55 i
10 15
6 12 35 查找方向
40 98
清华大学出版社
算法3.1——顺序查找
算法设计与分析
int SeqSearch1(int r[ ], int n, int k)
集合
//数组r[1] ~ r[n]存放查找
{ i=n; while (i>0 && r[i]!=k) i--; return i; }
BF C++
清华大学出版社
算法设计与分析
设串S长度为n,串T长度为m,在匹配成功的情况下, 考虑最坏情况,即每趟不成功的匹配都发生在串T的最后一 个字符。 例如:S="aaaaaaaaaaab" T="aaab" 设匹配成功发生在si处,则在i-1趟不成功的匹配中共 比较了(i-1)×m次,第i趟成功的匹配共比较了m次,所 以总共比较了i×m次,因此平均比较次数是:
清华大学出版社
算法设计与分析
3.2.2 串匹配问题
串匹配问题——给定两个串S=“s1s2…sn” 和T=“t1t2…tm”,在 主串S中查找子串T的过程称为串匹配,也称模式匹配。
串匹配问题属于易解问题。 串匹配问题的特征:
(1)算法的一次执行时间不容忽视:问题规模 n 很大, 常常需要在大量信息中进行匹配;
例:计算an
an=a×a×…×a
n次
清华大学出版社
算法设计与分析
蛮力法所赖的基本技术——扫描技 术
关键——依次处理所有元素 基本的扫描技术——遍历
(1)集合的遍历 (2)线性表的遍历
(3)树的遍历
(4)图的遍历
清华大学出版社
算法设计与分析
虽然巧妙和高效的算法很少来自于蛮力法,基于 以下原因,蛮力法也是一种重要的算法设计技术:
将待查值放在查找方向的尽头处,免去了在查找过 程中每一次比较后都要判断查找位置是否越界,从 而提高了查找速度。
0
k 哨兵 查找方向 i
1
2
3
4
5
6
7
8
9
10 15 24 6
12 35 40 98 55
清华大学出版社
算法3.2——改进的顺序查找
算法设计与分析
int SeqSearch2(int r[ ], int n, int k) //数组r[1] ~ r[n]存放查找集合 { r[0]=k; i=n; while (r[i]!=k) i --; return i; } 算法3.2的基本语句是r[i]!=k,其执行次数为:
a b c a c
j i j j j j
b
3
i=7,j=5失败
第 趟
4
a b a b c a b c a c b a a
j
b
s4=t2;t1≠t2 ∴t1≠s4
清华大学出版社 i
算法设计与分析
第 趟
a b a b c a b c a c b a b a
j i i
第 趟
i=11,j=6,t中全部字符 都比较完毕,匹配成功。
t1 … tnext[k]-1 tnext[k] … tk-1 tk … tj-next[k]+1 … tj-1 tj tj+1
最2大真前缀 最2大真后缀
清华大学出版社
算法设计与分析
例如,模式T="a b a a b a b c"的next值计算如下:
n m 1
1 m(n m 2) (i m) pi (i m) 2 i 1 i 1 n m 1
n m 1
清华大学出版社
算法设计与分析
改进的串匹配算法——KMP算法
设计思想:尽量利用已经部分匹配的结果信息, 尽量让主串 i 不回溯,加快模式串的滑动速度。