最長公共子串行 lcs:
動態規劃法得出以下:**有如下兩種方式實現:lcs(xm,yn) = lcs(xm-1,yn-1)+1 ## xm=yn
lcs(xm,yn) = max ## xm!=yn
1. 遞迴演算法
遞迴演算法實現,重點在於把它看成一顆二叉樹,進行的分解演算法。然而遞迴演算法計算重複度太高。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def lcs(str_x, coord_x, str_y, coord_y):
"""# 遞迴演算法實現,重點在於把它看成一顆二叉樹,進行的分解演算法。然而遞迴演算法計算重複度太高。
:param str_x:
:param coord_x: 初始值應傳入 len(str_x) - 1
:param str_y:
:param coord_y: 初始值應傳入 len(str_y) - 1
:return:
"""if coord_x < 0 or coord_y < 0:
return ""
if str_x[coord_x] == str_y[coord_y]:
return lcs(str_x, coord_x-1, str_y, coord_y-1) + str_x[coord_x]
else:
sub_node_left = lcs(str_x, coord_x-1, str_y, coord_y)
sub_node_right = lcs(str_x, coord_x, str_y, coord_y-1)
if len(sub_node_left) > len(sub_node_right):
return sub_node_left
else:
return sub_node_right
if __name__ == "__main__":
# strx = "bdcaba"
# stry = "abcbdab"
strx = "abcicba"
stry = "abdkscab"
print (lcs(strx, len(strx)-1, stry, len(stry)-1))
2. 二維陣列備忘法(與動態規劃法是兩回事)
"""# lcs 二維陣列備忘記法
:param s_x:
:param s_y:
:return:
"""len_x = len(s_x)
len_y = len(s_y)
print("初始化 %s*%s 的二維陣列" %(len_x,len_y))
storexy = [[0 for i in range(len_x+1)] for j in range(len_y+1)]
#print(storexy)
for y in range(1, len_y+1):
for x in range(1, len_x+1):
if strx[x-1] == stry[y-1]:
storexy[y][x] = storexy[y-1][x-1] + 1
else:
storexy[y][x] = max(storexy[y-1][x], storexy[y][x-1])
print("生成 字串:%s 和 字串 %s 的lcs備忘記法" % (s_x, s_y))
return storexy
def getlcs(storexy, s_x, s_y):
"""# lcs回溯法取值
:param storexy:
:param s_x:
:param s_y:
:return:
"""len_x = len(storexy[0])
len_y = len(storexy)
lcs_string = ""
x, y = len_x - 1, len_y - 1
while true:
if storexy[y][x] == 0:
break
if s_x[x-1] == s_y[y-1]:
lcs_string = s_x[x-1] + lcs_string
x, y = x-1, y-1
else:
if storexy[y][x-1] > storexy[y-1][x]:
x, y = x - 1, y
else: # storexy[y - 1][x] >= storexy[y][x - 1]:
x, y = x, y - 1
print("最長公共子串行為:%s" %lcs_string)
return lcs_string
if __name__ == "__main__":
storexy = producelcsxy(strx, stry)
for item in storexy:
print (item)
print(getlcs(storexy, strx, stry))
實踐:求兩字串的相似度
c : 最長公共子串序列
m:字元1長度
n:字元2長度
相似度 = 2 * c / (m + n)
LCS 最長公共子串行
問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上 公升的序列 i1,i2,ik 使得對 j 1,2,k,有 xij zj。比如z a,b,f,c 是 x a,b,c,f,b,c 的子串行。現在給出兩個序列 x和 y,你的任務是找到 x和 y的最大公共子...
LCS最長公共子串行
求兩個字串的最大公共子串行問題 子串行的定義 若給定序列x 則另一串行z 是x的子串行是指存在乙個嚴格遞增下標序列使得對於所有j 1,2,k有 zj xij。例如,序列z 是序列x 的子序列,相應的遞增下標序列為。分析 用動態規劃做 1.最長公共子串行的結構 事實上,最長公共子串行問題具有最優子結構...
LCS最長公共子串行
lcs是longest common subsequence的縮寫,即最長公共子串行。乙個序列,如果是兩個或多個已知序列的子串行,且是所有子串行中最長的,則為最長公共子串行。複雜度對於一般的lcs問題,都屬於np問題。當數列的量為一定的時,都可以採用動態規劃去解決。解法動態規劃的乙個計算最長公共子串...