計算最長公共子串行(LCS)的兩種演算法

2021-09-25 07:31:12 字數 3016 閱讀 5307

最長公共子串行 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問題。當數列的量為一定的時,都可以採用動態規劃去解決。解法動態規劃的乙個計算最長公共子串...