Hunt-Szymanski算法的Python实现

Hunt-Szymanski算法 Python实现

该算法是LCS(Longest Common Subsequence)问题的一个优化算法由Hunt and Szymanski在1977年提出,网上找了很久但是都没有一个很详细的解释和代码实现,理解的过程也是云里雾里,,所以现在先把老师给的标准答案写在这,之后自己学懂了再慢慢解释,老师的代码是Python实现的。(之后如果有学弟学妹发现了这篇帖子后,,别给老板打小报告哈,,)

以下是该算法的完整代码:

def similarity_Hunt_and_Szymanski(s1, s2):
    """Return the similarity between two strings,
    i.e., the maximal number of characters in the same order in the two strings
    Algorithm: [Hunt and Szymanski, 1977] in O((|d| + log(r)) x log(min(|s1|,|s2|)))
    where d is the number of different symbols in the longest string
    and r is the number of positions with the same symbol in the two strings (equality points)

    >>> similarity_Hunt_and_Szymanski('','abcd')
    0
    >>> similarity_Hunt_and_Szymanski('abcd','abcd')
    4
    >>> similarity_Hunt_and_Szymanski('abcd','wxyz')
    0
    >>> similarity_Hunt_and_Szymanski('abcd','wxabyd')
    3
    """
    # let s1 be the shortest string
    if len(s1) > len(s2):
        s1, s2 = s2, s1
    equal = {}

    # particular cases
    if '' == s1:
        return 0

    # first preprocessing step: computation of the equality points
    for i in range(0, len(s2)):
        equal[i + 1] = list_of_indices(s2[i], s1)[::-1]

    # second preprocessing step: similarity threshold table
    threshold = [len(s1) + 1 for _ in range(0, len(s2) + 1)]
    threshold[0] = 0
    # processing step: algorithm proper
    for i in range(0, len(s2)):
        for j in equal[i + 1]:
            k = look_for_threshold_index(j, threshold)  # look for k such that threshold[k-1] < j <= threshold[k]:
            if j < threshold[k]:
                threshold[k] = j

    # postprocessing step: looking for the result, i.e., the similarity between the two strings
    # it is the first index in threshold with a value different from len(s1) + 1, starting from the right
    result = 0
    for k in range(len(s2), 0, -1):
        if len(s1) + 1 != threshold[k]:
            result = k
            break
    return result

def list_of_indices(c, s):
    """
    Returns the list of indices of the occurrences of c in s
    """
    result = []
    i = 0
    while i < len(s):
        if type(s) == list:
            try:
                i = s[i:].index(c) + i + 1
            except ValueError:
                i = 0
        else:
            i = s.find(c, i) + 1

        if 0 != i:
            result.append(i - 1)
        else:
            break
    return result

def look_for_threshold_index(j, threshold, left=None, right=None):
    """
    Look for k such that threshold[k-1] < j <= threshold[k]
    Algorithm: dichotomy search

    >>> look_for_threshold_index(4,[4])
    0
    >>> look_for_threshold_index(4,[0, 1, 2, 3, 4, 5, 6, 7])
    4
    >>> look_for_threshold_index(5,[0, 2, 4, 6, 8, 10, 12, 14])
    3
    """

    if (None, None) == (left, right):
        left, right = 0, len(threshold) - 1

    if left > right:
        raise ValueError('Value in left higher than right')
    elif left + 1 == right or left == right:
        return right
    else:
        mid = int((left + right) / 2)
        if j <= threshold[mid]:
            left, right = left, mid
        else:
            left, right = mid, right
        return look_for_threshold_index(j, threshold, left, right)    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Deflate算法和LZSS(Lempel-Ziv-Storer-Szymanski)算法都是数据压缩算法,它们在数据压缩效率、速度和应用场景上各有特点。 **Deflate算法**: - 优点: - **高效性**:采用混合编码,结合了LZ77和Huffman编码,能有效减少重复数据,尤其对于文本和二进制数据有很好的压缩效果。 - **标准广泛**:Deflate是ZIP和gzip文件格式的基础,也是HTTP传输中的内容编码(gzip)。 - **兼容性好**:由于其广泛应用,许多程序都能处理被Deflate压缩的数据。 - 缺点: - **压缩率相对有限**:对于某些类型的数据(如已压缩的数据或结构化的数据),Deflate的压缩效果可能不如其他算法。 - **解压过程可能较慢**:如果解压性能对应用来说是一个关键因素,可能会有所牺牲。 **LZSS算法**: - 优点: - **简单易实现**:LZSS算法的核心思想是基于前缀匹配,实现起来比较简单,适合资源受限的环境。 - **速度快**:LZSS的压缩过程通常比Deflate更快,因为它不需要复杂的编码结构。 - 缺点: - **压缩率较低**:LZSS更适合于数据流中的局部重复,对于全局重复较多的数据,压缩效果较差。 - **压缩/解压的内存开销大**:LZSS算法需要存储多个匹配前缀,这可能导致较大的内存占用。 - **不支持无损压缩**:LZSS不是一种无损压缩算法,原始数据无法完全恢复,只适用于对数据有轻微修改容忍的应用。 **总结**: Deflate适用于对压缩率要求高且能接受一定解压延迟的场景,如网络传输和文件存储。LZSS则更适合作为实时压缩(如视频编码前的预处理),或者在内存有限的设备上进行快速压缩。两者各有适用范围,选择哪个取决于具体需求和性能要求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值