徐静蕾,用动态规划算法核算字符串的修改间隔,守岁是什么意思
作者: jclian,喜爱算法,酷爱共享,希望能结交更多情投意合的朋友,一同在学习Python的道路上走得更远!
修正间隔问题
什么是两个字符串的修正间隔(edit distance)?给定字符串s1和s2,以及在s1上的如下操作:
刺进(Insert)一个字符
移除(Remove)一个字符
替换(Replace)一个字符
试问最小需求多少次这样的操作才干使得s1转换为s2?
比方,单词“cat”和“hat”,这样的操作最少需求一次,只需求把“cat”中的“c”替换为“h”即可。单词“recall”和“call”,这样的操作最少需求两次,只需求把“recall”中的“r”和“e”去掉即可。单词“Sunday”和“Saturday”,这样的操作最少需求3次,在“Sunday”的“S”和“u”中刺进“a”和“t”,再把“n”替换成“r”即可。
那么,是否存在一种高效的算法,能够快速、精确地核算出两个字符串的修正间隔呢?
动态规划算法
咱们运用动态规划算法(Dynamic Programming)来核算出两个字符串的修正间隔。
咱们从两个字符串s1和s2的最结尾向前遍向来考虑。假定s1的长度为m,s2的长度为n,算法如下:
假如两个字符串的最终一个字符相同,那么,咱们就能够递归地核算长度为m-1和n-1的两个字符串的景象;
假如两个字符串的最终一个字符不相同,那么,进入以下三种景象:
刺进: 递归地核算长度为m和n-1的两个字符串的景象,这是由于在s1中的结尾刺进了一个s2的最终一个字符,这样s1和s2的结尾字符相同,便是1中景象;
删去: 递归地核算长度为m-1和n的两个字符串的景象,这是在s1中的结尾删去了一个字符;
替换: 递归地核算长度为m-1和n-1的两个字符串的景象,这是由于把s1中结尾字符替换成了s2的最终一个字符,这样s1和s2的结尾字符相同,便是1中景象;
这样,咱们就有了子结构问题。关于动态规划算法,咱们还需求一个初始化的进程,然后中心保护一张二维表即可。初始化的进程如下: 假如m为0,则至少需求操作n次,即在s1中逐一增加s2的字符,一共是n次;假如n为0,则至少需求操作m次,即把s1的字符逐一删去即可,一共是m次。
Python完成
使用DP算法处理两个字符串的修正间隔的Python代码如下:
# -*- coding: utf-8 -*-
# using Dynamic Programming to solve edit distance problem
# s1, s2 are two strings
def editDistDP(s1, s2):
m, n = len(s1), len(s2)
# Create a table to store results of subproblems
dp = [[0 for _ in range(n+1)] for _ in range(m+1)]
# using DP in bottom-up manner
for i in range(m + 1):
for j in range(n + 1):
# If first string is empty, only option is to
# isnert all characters of second string, thus 徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思the
# min opration is j
if i == 0:
dp[i][j] = j
# If second string is empty, only option is to
# remove all characters of second string, thus the
# min opration is i
elif j == 0:
dp[i][j] = i
# If last characters are same, ignore last character
&nbs腹轮机p; &k9606nbsp; # and recursive for remaining string
elif s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1]
# If last character are different, consider all
&ndnf令郎bsp; # possibilities and find minimum of inserting, removing, replacing
else:
dp[i][j] = 陈蓉赵健;1 + min(dp[i][j-1], # Insert
dp[i-概组词1][j], # Remove
dp[i-1][j-1]) # Replace
return dp[m][n]
# Driver program
s1 = "sunday"
s2 = "saturday"
edit_distance = editDistDP(s1, s2)
print("The Edit徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思 Distance of '%s' and '%s' is %d."%(s1, s2,&nbs巧织馆织造视频全集p;edit_distance))
输出成果如下:
The Edit 大柠和林知逸的相片;Distance of 'sunday' and 'saturday' is&nb日本小女子sp;3.
Java完成
使用DP算法处理两个字符串的修正间隔的Java代码如下:
package DP_example;
// 核算两个字符串的修正间隔(Edit Distance)
public class Edit_Distance {
// 主函数
public static void main(String[] args) {
String str1 = "cat";//"Sunday";
String str2 = "hat";//"Saturday";
int edit_dist = edit_distance(str1, str2);
System.out.println(String.format("The edit distance of '%s' and '%s' is %d.",
str1, str2, edit_dist));
}
/*
函数edit_distanc: 核算两个字符串的修正间隔(Edit Distance)
传入参数: 两个字符串str1和str2
回来: 修正间隔
&nb徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思sp; */
public static int edit_distance(String str1, String str2){
// 字符串的长度
int m = str1.length();
int n = str2.length();
// 初始化表格,用于保护子问题的解
int[][] dp = new int[m+1][n+1];
小布尔乔亚情调 for(int i=0; i <= m; i++)
for(int j=0; j <= n; j++)
米仓穗香 dp[i][j] = 0;
// using DP in bottom-up&nbs唐末枭雄p;manner
for(int i=0;&n80岁巨型娃娃鱼bsp;i <= m; i++){
for(int j=0; j <= n; j++) {
/* If first string 徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思;is empty, only option is to
 帝刃雷神; * isnert all characters of second string, thus the
 徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思; &n许哲珮bsp; * min opration is j
*/
if(i == 0) { dp[i][j] = j;}
/* If second st徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思ring is empty, only option is to
* remove all char战狼徐佳雯acters of second string, thus the
* min opration is i
*/
else if(j == 0){dp[i][j] = i;}
&n徐静蕾,用动态规划算法核算字符串的修正间隔,守岁是什么意思bsp; /* If last characters are same, ignore last character
* and recursive for remaining string
*/
else if(str1.charAt(i-1) == str2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}
 干伏苓块怎么食用办法; /*If last character are different, consider all
邱云光 *possibilities and find minimum of inserting, removing, replacing
*/
else{
/*
* dp[i][j-1]: Insert
* dp[i-1][j]: Remove
* dp[i-1][j-1]: Replace
*/
dp[i][j] = 1 + min(min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]);
}
}
}
 李建海河北; return dp[m][n];
}
public static int min(int i, int j)xaxkiz{
return (i <= j) ? i : j;
}
}
输出成果如下:
The edit distance of 'cat' and 'hat' is 1.
其它完成办法
以上,咱们用Python和Java以及动态规划算法自己完成了修正间隔的核算。当然,咱们也能够调用第三方模块的办法,比方NTLK中的edit_distance()函数,示例代码如下:
# 使用NLTK中的edit_distance核算两个字符串的Edit Distance
from nltk.metrics import edit_distance
s1 = "recall"
s2 = "call"
t = edit_distance(s1, s2)
print("The Edit Distance of '%s' and '%s' is %d." % (s1, s2, t))
输出成果如下:
The Edit Distance of 'recall' and 'call' is 2.
总结
在本文中,咱们关于两个字符串的修正间隔的核算,只采用了刺进、删去、替换这三种操作,在实践中,或许还会有更多的操作,比方旋转等。当然,这并不是要点,要点是咱们需求了解处理这类问题的算法,即动态规划算法。
引荐Python中文社区旗下的几个效劳类大众号
▼ 长按扫码上方二维码或点击下方阅览原文
免费成为社区注册会员,会员能够享用更多权益
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。