编辑距离 php,编辑距离问题(示例代码)

问题:

讨论:

这个题我在华为笔试的时候遇到过,直接看懵了。无意中在知乎上发现有人讨论这个题(https://zhuanlan.zhihu.com/p/111409982),稍微弄懂了些皮毛,

所以记录一下。

简单的说一下例子:

有字符串“horse” 和字符串“ros”,问从“horse”转化到“ros”要多少步(包括增加(“hor”>"hors", 增加了一个s),删除("horse"->"hors",删除了一个e),改变("horse"->"horst", 由‘e‘->‘t‘))

这个一般很难想到要用动态规划来做。那么要务是找到递推公式。

从最基本的情况考虑,也就是""->"",需要的步骤是0,那么从""->"ros"最少的步骤则是3(依次增加[r, o, s])。

从"horse"->""的情况同理,是5(依次删除[h,o,r,s,e])。

设dp[i][j]为"horse"[1..i]转换为"ros"[1..j]

那么考虑一下比较现实的“horse”到"ros":“horse”的第i个字符和“ros”第j个做比较的时候

case 1:

horse[i+1] == ros[j+1]

那么不需要多余操作,也就说说dp[i][j] == dp[i+1][j+1]

case 2:

horse[i+1] != ros[j+1]

那么这里的问题就是,如何操作才能让horse[1..i+1] ->ros[1..j+1]了

如题目给出的条件,能够进行的操作有3种,假设实际情况为"hor"->"ro"时出现case 2

1. 增加

也就是说,需要"hor"增加一个字符才能转变成"ro"

如果要计算这次的edit的次数,我们需要知道"hor"->"r"的次数,也就是dp[i+1][j]的值。

原因是,我们需要在"hor"上多加一个字符来使"horo"->"ro","hor"->"r",转换好了以后,再来一个增加操作

2. 删除

这里要让"hor"->"ro"使用删除操作,删除"horse"[i+1]让"hor"->"ro", 那么需要的是"ho"->"ro", 也就是dp[i][j+1]

3. 改变

"hor" -> "ro"使用改操作的时候,需要知道"ho"->"r"的转换需要的操作。

因为是最少的操作数量,所以需要使用min来找到这三种对应的那种操作的数量最小

#word1(horse) to word2(ros)

defedit_distance(word1, word2):

m=len(word1)

n=len(word2)

dp= [[0 for _ in range(n+1)] for _ in range(m+1)]for i in range(m+1):for j in range(n+1):if j ==0:

dp[i][j]= i #"horse" to ""

if i ==0:

dp[i][j]= j #"" to "ros"

for i in range(1,m+1):for j in range(1, n+1):if word1[i-1] == word2[j-1]:

dp[i][j]= dp[i-1][j-1]else:

inc= dp[i-1][j] + 1update= dp[i-1][j-1] + 1delete= dp[i][j-1] + 1dp[i][j]=min([inc, update, delete])return dp[-1][-1]if __name__ == "__main__":

res= edit_distance("horse", "ros")print(res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值