我试图返回两个字符串之间公共子字符串的长度。我对DP解决方案非常了解,但是我希望能够为练习而递归地解决此问题。
我可以找到最长的公共子序列...
def get_substring(str1, str2, i, j):
if i == 0 or j == 0:
return
elif str1[i-1] == str2[j-1]:
return 1 + get_substring(str1, str2, i-1, j-1)
else:
return max(get_substring(str1, str2, i, j-1), get_substring(str1, str2, j-1, i))
但是,我需要最长的公共子字符串,而不是最长的公共字母序列。我尝试通过几种方式更改代码,其中一种是将基本情况更改为...
if i == 0 or j == 0 or str1[i-1] != str2[j-1]:
return 0
但是那没有用,我的其他尝试也没有。
例如,对于以下字符串...
X = "AGGTAB"
Y = "BAGGTXAYB"
print(get_substring(X, Y, len(X), len(Y)))
最长的子字符串是 AGGT 。
我的递归技能不是最好的,所以如果有人可以帮助我,那将非常有帮助。
答案 0 :(得分:2)
package algo.dynamic;
公共类LongestCommonSubstring {
public static void main(String[] args) {
String a = "AGGTAB";
String b = "BAGGTXAYB";
int maxLcs = lcs(a.toCharArray(), b.toCharArray(), a.length(), b.length(), 0);
System.out.println(maxLcs);
}
private static int lcs(char[] a, char[] b, int i, int j, int count) {
if (i == 0 || j == 0)
return count;
if (a[i - 1] == b[j - 1]) {
count = lcs(a, b, i - 1, j - 1, count + 1);
}
count = Math.max(count, Math.max(lcs(a, b, i, j - 1, 0), lcs(a, b, i - 1, j, 0)));
return count;
}
}
答案 1 :(得分:1)
您需要分别递归递归。如果您具有多个递归函数,那么这样做更容易。
def longest_common_substr_at_both_start (str1, str2):
if 0 == len(str1) or 0 == len(str2) or str1[0] != str2[0]:
return ''
else:
return str1[0] + longest_common_substr_at_both_start(str1[1:], str2[1:])
def longest_common_substr_at_first_start (str1, str2):
if 0 == len(str2):
return ''
else:
answer1 = longest_common_substr_at_both_start (str1, str2)
answer2 = longest_common_substr_at_first_start (str1, str2[1:])
return answer2 if len(answer1) < len(answer2) else answer1
def longest_common_substr (str1, str2):
if 0 == len(str1):
return ''
else:
answer1 = longest_common_substr_at_first_start (str1, str2)
answer2 = longest_common_substr(str1[1:], str2)
return answer2 if len(answer1) < len(answer2) else answer1
print(longest_common_substr("BAGGTXAYB","AGGTAB") )
答案 2 :(得分:1)
对不起。我没有时间将其转换为递归函数。这是比较直接的组成。如果Python具有fold
函数,则可以大大简化递归函数。 90%的递归函数是原始函数。这就是fold
如此有价值的原因。
我希望其中的逻辑有助于递归版本。
(x,y)= "AGGTAB","BAGGTXAYB"
xrng= range(len(x)) # it is used twice
np=[(a+1,a+2) for a in xrng] # make pairs of list index values to use
allx = [ x[i:i+b] for (a,b) in np for i in xrng[:-a]] # make list of len>1 combinations
[ c for i in range(len(y)) for c in allx if c == y[i:i+len(c)]] # run, matching x & y
...生成此列表以从中获取最长的比赛
['AG','AGG','AGGT','GG','GGT','GT']
我不知道要从列表中获得最长的比赛会有点麻烦。
ls= ['AG', 'AGG', 'AGGT', 'GG', 'GGT', 'GT']
ml= max([len(x) for x in ls])
ls[[a for (a,b) in zip(range(len(ls)),[len(x) for x in ls]) if b == ml][0]]
“ AGGT”