整理字符串处理Word文档下载推荐.docx
《整理字符串处理Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《整理字符串处理Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
j]
=
Min
(
f[i-1,
j]+1,
j-1]+1,
j-1]+(str_a[i]==str_b[j]
?
0
:
1)
)
维基百科中的描述如下:
1)递归方法(用到动态规划)
由上述的递归公式可以有以下代码:
[cpp]
viewplaincopy
1.//求两个字符串的编辑距离问题
2.//递归版本,备忘录C[i,j]表示strA[i]...strA[size_A-1]与strB[j]...strB[size_B-1]的编辑距离
3.int
editDistance_mem(char
*strA,int
size_A,char
*strB,int
size_B){
4.
int
**C=new
int*[size_A+1];
5.
for(int
i=0;
i<
=size_A;
i++){
6.
C[i]=new
int[size_B+1]();
7.
}
8.
//初始化
9.
10.
j=0;
j<
=size_B;
j++)
11.
C[i][j]=INT_MAX;
12.
13.
res=EDM(C,strA,0,size_A-1,strB,0,size_B-1);
14.
//free
mem
15.
16.
delete
[]
C[i];
17.
18.
C;
19.
return
res;
20.}
21.int
EDM(int
**C,char
i,int
A_end,char
j,int
B_end){
22.
if(C[i][j]<
INT_MAX)//做备忘
23.
C[i][j];
24.
if(i>
A_end){
25.
if(j>
B_end)
26.
C[i][j]=0;
27.
else
28.
C[i][j]=B_end-j+1;
29.
}else
30.
A_end)
31.
32.
33.
C[i][j]=A_end-i+1;
34.
35.
if(strA[i]==strB[j])
36.
C[i][j]=EDM(C,strA,i+1,A_end,strB,j+1,B_end);
37.
else{
38.
a=EDM(C,strA,i+1,A_end,strB,j+1,B_end);
39.
b=EDM(C,strA,i,A_end,strB,j+1,B_end);
40.
c=EDM(C,strA,i+1,A_end,strB,j,B_end);
41.
C[i][j]=min(a,b,c)+1;
42.
43.
44.}
2)矩阵标记法
递推方法(也可称为矩阵标记法),通过分析可知可以将f[i,
j]的计算在一个二维矩阵中进行,上面的递推式实际上可以看做是矩阵单元的计算递推式,只要把矩阵填满了,f[la-1,
lb-1]的值就是要求得最小编辑距离。
代码如下:
2.//递推版本
C[i,j]表示strA[i]...strA[size_A-1]与strB[j]...strB[size_B-1]的编辑距离
editDistance_iter(char
i=size_A;
i>
=0;
i--){
j=size_B;
j>
j--){
size_A-1){
size_B-1)
C[i][j]=size_B-j;
size_B-1){
size_A-1)
C[i][j]=size_A-i;
20.
21.
C[i][j]=C[i+1][j+1];
C[i][j]=min(C[i+1][j+1],C[i+1][j],C[i][j+1])+1;
res=C[0][0];
33.}
六、最长不重复子串
很好理解,即求一个串内最长的不重复子串。
1)使用Hash
要求子串中的字符不能重复,判重问题首先想到的就是hash,寻找满足要求的子串,最直接的方法就是遍历每个字符起始的子串,辅助hash,寻求最长的不重复子串,由于要遍历每个子串故复杂度为O(n^2),n为字符串的长度,辅助的空间为常数hash[256]。
1./*
最长不重复子串
我们记为
LNRS
*/
2.int
maxlen;
maxindex;
4.void
output(char
*
arr);
5./*
基本算法
hash
6.char
visit[256];
7.void
LNRS_hash(char
arr,
size)
8.{
i
0;
<
size;
++i)
{
memset(visit,0,sizeof(visit));
visit[arr[i]]
1;
j
i+1;
++j)
if(visit[arr[j]]
==
0)
visit[arr[j]]
19.else
if(j-i
>
maxlen)
maxlen
-
i;
maxindex
break;
output(arr);
31.}
2)动态规划法
字符串的问题,很多都可以用动态规划处理,比如这里求解最长不重复子串,和前面讨论过的最长递增子序列问题就有些类似,在LIS(最长递增子序列)问题中,对于当前的元素,要么是与前面的LIS构成新的最长递增子序列,要么就是与前面稍短的子序列构成新的子序列或单独构成新子序列。
这里我们采用类似的思路:
某个当前的字符,如果它与前面的最长不重复子串中的字符没有重复,那么就可以以它为结尾构成新的最长子串;
如果有重复,那么就与某个稍短的子串构成新的子串或者单独成一个新子串。
我们来看看下面两个例子:
1)字符串“abcdeab”,第二个a之前的最长不重复子串是“abcde”,a与最长子串中的字符有重复,但是它与稍短的“bcde”串没有重复,于是它可以与其构成一个新的子串,之前的最长不重复子串“abcde”结束;
2)字符串“abcb”,跟前面类似,最长串“abc”结束,第二个字符b与稍短的串“c”构成新的串;
我们貌似可以总结出一些东西:
当一个最长子串结束时(即遇到重复的字符),新的子串的长度是与(第一个重复的字符)的下标有关的。
于是类似LIS,对于每个当前的元素,我们“回头”去查询是否有与之重复的,如没有,则最长不重复子串长度+1,如有,则是与第一个重复的字符之后的串构成新的最长不重复子串,新串的长度便是当前元素下标与重复元素下标之差。
可以看出这里的动态规划方法时间复杂度为O(N^2),我们可以与最长递增子序列的动态规划方