求最长公共子串

你的名字 2022-02-01 15:15 368阅读 0赞

文章目录

  • 求最长公共子串
    • 思路一
    • 思路二
    • 思路三

求最长公共子串

  • 最长公共子串最好的算法是动态规划。其次KMP算法也是解决这类方法中比较好的实现。

思路一

  • 最慢方法,两个字符中每个元素都依次比较,如果相同就检测最长相同串。

    思路一,最慢方法,两个字符中每个元素都依次比较,如果相同就检测最长相同串。

    str1 = “aabcdefgh”
    str2 = “aaabcdef”

    str1 = “aaaaaaabbbbbcccccccccccccdddddddddddd”

    str2 = “bbbaaaaacccccccccccdddddddddddddddddddaaaaaaaaaaaaaaa”

    def getMaxsame1(str1,str2):

    1. compare = 0
    2. maxcount = 0
    3. maxsame = set()
    4. for i,one in enumerate(str1):
    5. end = i
    6. for k in range(len(str2)):
    7. compare += 1
    8. while end<len(str1) and k<len(str2) and str1[end]==str2[k]:
    9. compare +=1
    10. end += 1
    11. k += 1
    12. if end != i: #进入过循环体
    13. compare -= 1 #取出重复记录的一次
    14. temp = end-i
    15. if maxcount<temp:
    16. maxsame = { str1[i:end]}
    17. maxcount = temp
    18. elif maxcount==temp:
    19. maxsame.add(str1[i:end])
    20. end = i

    print(compare)

    1. return maxsame

    getMaxsame(str1,str2)

    for i in getMaxsame1(str1,str2):

    1. print(i,len(i))

思路二

  • 对最短字符建立,字符与索引的k:v对,v为索引范围的列表。如:{a:[a所出现的索引]},依次从最长字符中遍历,匹配出现的索引位置最长的相同串。求出最长公共子串

    from collections import defaultdict

    思路二 对最短字符建立,字符与索引的k:v对,v为索引范围的列表。如:{a:[a所出现的索引]},

    依次从最长字符中遍历,匹配出现的索引位置最长的相同串。求出最长公共子串

    str1 = “aabcdefgh”
    str2 = “aaabcdef”

    str1 = “aaaaaaabbbbbcccccccccccccdddddddddddd”

    str2 = “bbbaaaaacccccccccccdddddddddddddddddddaaaaaaaaaaaaaaa”

    def getMaxsame2(str1,str2):

    1. if len(str1)>len(str2):
    2. str1,str2 = str2,str1
    3. indexset = defaultdict(list)
    4. #从最短字符串中获取字典,进可能的节约空间
    5. for i,one in enumerate(str1):
    6. indexset[one].append(i)
    7. compare = 0
    8. maxcount = 0
    9. maxsame = set()
    10. #遍历最长字符串
    11. for i,one in enumerate(str2):
    12. for k in indexset.get(one,[]):
    13. compare += 1
    14. end = i+1
    15. k += 1
    16. while end<len(str2) and k<len(str1) and str2[end]==str1[k]:
    17. compare += 1
    18. end += 1
    19. k += 1
    20. temp = end-i

    print(temp,i,end,k)

    1. if maxcount<temp:
    2. maxsame = { str2[i:end]}
    3. maxcount = temp
    4. elif maxcount == temp:
    5. maxsame.add(str2[i:end])

    print(compare)

    1. return maxsame

    for i in getMaxsame2(str1,str2):

    1. print(i,len(i))

思路三

  • 使用动态规划。
  • 建立str1* str2的矩阵,相同赋值1不同赋值0.求右斜线连续为1的最长集合即为最长公共子串

    思路三,使用动态规划。建立str1* str2的矩阵,相同赋值1不同赋值0.求右斜线连续为1的最长集合即为最长公共子串

    str1 = “aabcdefgh”
    str2 = “aaabcdef”
    def getMaxsame3(str1,str2):

    1. arr1 = [] #动态规划模拟矩阵
    2. maxcount = 0;#记录最长字符串的长度
    3. maxstr = [] #记录所有最长字符串的结束索引
    4. for n1,v1 in enumerate(str1):
    5. arr1.append([])
    6. for n2,v2 in enumerate(str2):
    7. if v2==v1:
    8. i = n1 -1
    9. k = n2 -1
    10. if i>=0 and k>=0:
    11. temp = arr1[i][k]+1
    12. arr1[n1].append(temp)
    13. if maxcount<temp:
    14. maxstr = [(n1,n2)]
    15. maxcount = temp
    16. elif maxcount==temp:
    17. maxstr.append((n1,n2))
    18. else:
    19. arr1[n1].append(1)
    20. if maxcount <1:
    21. maxstr = [(n1,n2)]
    22. maxcount = 1
    23. elif maxcount == 1:
    24. maxstr.append((n1,n2))
    25. else:
    26. arr1[n1].append(0)
    27. arrdict = { str1[n1+1-maxcount:n1+1] for n1,n2 in maxstr}
    28. return arrdict,maxcount

    getMaxsame3(str1,str2)

发表评论

表情:
评论列表 (有 0 条评论,368人围观)

还没有评论,来说两句吧...

相关阅读

    相关 公共

    最长公共子串(注意子串是连续的,也是与最长公共子序列的区别) 1、先建立一个二维数组array\[str1.size()\]\[str2.size()\](全部初始化为0