Python动态规划(最大公共字符串和最大公共子序列)

求最大公共字符串

代码:

def LCS_str(s1, s2):
    # 求2个字符串的最大公共字符串
    # 求对角线上的
    arr = [[0 for i in range(len(s2) + 1)] for j in range(len(s1) + 1)]
    print(arr)
    max = 0
    p = 0
    for i in range(len(s1)):
        for j in range(len(s2)):
            if s1[i] == s2[j]:
                arr[i][j] = arr[i - 1][j - 1] + 1
                if arr[i][j] > max1:
                    max = arr[i][j]
                    p = i + 1
    print(arr)
    return s1[p - max:p], max


print(LCS_str('abcdfga', 'abdfg'))

思路:根据2个字符串的长度,构造对应的矩阵,来记录2个字符串每个字符的匹配情况。
如果匹配,对应位置a[i][j]的值为左上角的值加1,max记录最大公共字符串的长度,p记录最大公共字符串末尾位置的后一个位置。
函数返回最大公共字符串及其长度

求最大公共子序列

子序列:某个序列的子序列指从原序列中不破坏顺序地任意除去若干个字符后形成的序列。

import numpy
def find_lcseque(s1, s2):
    # 生成字符串长度加1的0矩阵,m用来保存对应位置匹配的结果
    m = [ [ 0 for x in range(len(s2)+1) ] for y in range(len(s1)+1) ]
    # d用来记录转移方向
    d = [ [ None for x in range(len(s2)+1) ] for y in range(len(s1)+1) ]

    for p1 in range(len(s1)):
        for p2 in range(len(s2)):
            if s1[p1] == s2[p2]:  # 字符匹配成功,则该位置的值为左上方的值加1
                m[p1 + 1][p2 + 1] = m[p1][p2] + 1
                d[p1 + 1][p2 + 1] = 'ok'
            elif m[p1 + 1][p2] > m[p1][p2 + 1]:# 左值大于上值,则该位置的值为左值,并标记回溯时的方向
                m[p1 + 1][p2 + 1] = m[p1 + 1][p2]
                d[p1 + 1][p2 + 1] = 'left'
            else:    # 上值大于左值,则该位置的值为上值,并标记方向up
                m[p1 + 1][p2 + 1] = m[p1][p2 + 1]
                d[p1 + 1][p2 + 1] = 'up'
    print(numpy.array(m))
    print(numpy.array(d))
    s = []
    while m[p1][p2]:  # 不为None时
        c = d[p1][p2]
        if c == 'ok':  # 匹配成功,插入该字符,并向左上角找下一个
            s.append(s1[p1 - 1])
            p1 -= 1
            p2 -= 1
        if c == 'left':
# 根据标记,向左找下一个
            p2 -= 1
        if c == 'up':  # 根据标记,向上找下一个
            p1 -= 1
    s.reverse()
    return ''.join(s)
print(find_lcseque('abcdfga', 'abdfgb'))

思路:生成2个矩阵,一个矩阵记录字符串匹配情况,一个矩阵记录转移方向。
如果匹配,对应矩阵位置的值为左上方加1,不匹配则取上方或左上方的最大值。
其他的看注释

def loadData(filename):
    import jieba
    txt = open(filename).read()
    words = jieba.lcut(txt) #读取中文字符
    return words

这可以拿来对比文章相似度,引入jieba库即可(太大的不要尝试,容易死机)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值