最長公用子序列是很基本的演算法,只是最近用到了就又拿來學習一下,網上有很多很多的Java版本的,的確寫的也很不錯,思想都很好,大致上分為三種:
1.基於遞迴的思想
2.基於動態規劃的思想
3.基於HashMap的動態規劃
在這裡我使用的是python來實現,方法很簡單,先看程式:
#!usr/bin/env python#encoding:utf-8'''__Author__:沂水寒城功能:計算字串之間的最長公用子序列'''def get_lcs(string1, string2): ''' 輸入:待比較的兩個字串 輸出:降序輸出的(子序列長度,子序列)列表 ''' string1_list=list(string1) string2_list=list(string2) lcs_list=[] for i in range(len(string1_list)): flag=0 lcs='' for j in range(i,len(string1_list)): for k in range(flag, len(string2_list)): if string1_list[j]==string2_list[k]: lcs+=string1_list[j] flag=k+1 lcs_list.append((len(lcs), lcs)) print len(lcs_list) return sorted(lcs_list, reverse=True)if __name__ == '__main__': lcs_list=get_lcs("abcdjio7890bhsdjknyewhbnvd", "djio78347bvfdjbnknyew") print lcs_list
結果如下:
26[(11, 'io77bbknyew'), (10, 'o77bbknyew'), (9, 'ddjbknyew'), (9, 'ddjbknyew'), (9, '77bbknyew'), (8, 'jjbknyew'), (8, 'ddjknyew'), (8, 'ddjknyew'), (8, 'ddjknyew'), (8, '8bbknyew'), (7, 'jjknyew'), (7, 'bbknyew'), (7, 'bbknyew'), (7, 'bbknyew'), (7, 'bbknyew'), (7, 'bbknyew'), (5, 'nnyew'), (5, 'knyew'), (4, 'bbnn'), (4, 'bbnn'), (3, 'yew'), (2, 'vd'), (2, 'nn'), (2, 'ew'), (2, 'dd'), (1, 'w')][Finished in 0.5s]
演算法的思想也很簡單,這裡簡單說一下:首先將字串轉換成字串列表形式,以第一個字串為基準開始迴圈遍曆比較,設定標誌位,目的是為了只比較第二個字串跟第一個字串字元相同位置之後的字串,而不重頭開始比較,保證了效率的同時保證了得到的子序列中的元素相對位置與原始字串中各個元素的相對位置是相同的。