zoukankan      html  css  js  c++  java
  • 数据结构和算法: 字符串匹配(一) BF/RK

    1.BF算法

    暴力匹配, 也叫朴素匹配算法. 所以效率低.
    如在字符串A中查找B, A就是主串(长度n), B是模式串(长度m). 该算法就是在主串中检查起始位置分别是0,1,2,...,n-m且长度为m的n-m+1个子串

    比如两个字符串相似度很高. 但是在工程中却经常用该算法, 因为

    • 大部分情况下两个字符串的长度都不会太长, 而且对比过程中如果不一致可以提前退出
    • 思想简单, 不容易出错

    时间复杂度: O(n*m)

    # coding:utf-8
    
    
    
    class Bf(object):
        """
        字符串匹配: BF算法(暴力匹配)
        """
    
        def match(self, string1: str, string2: str):
            """
            :param string1: 主串
            :param string2: 模式串
            :return:
            """
            n = len(string1)
            m = len(string2)
            loop_nums = n - m + 1
            for i in range(loop_nums):
                for j in range(m):
                    if string1[i] == string2[j]:
                        i += 1
                        continue
                    else:
                        break
                else:
                    return True
            return False
    
    
    if __name__ == "__main__":
        bf = Bf()
        assert bf.match("abcabc", "ca") == True
        assert bf.match("abcabc", "bc") == True
        assert bf.match("abcabc", "cc") == False
        assert bf.match("abcabc", "cab") == True
        assert bf.match("abcabc", "cb") == False
    
    

    2.RK算法

    对BF算法引入hash算法, 是升级版.

    通过hash算法分别对主串中的n-m+1个子串分别求哈希值, 最后再与模式串的哈希值对比. 因为哈希值是一个数字, 所以速度很快. 为了避免因hash冲突导致的错误, 当匹配到两个字符串相等时再对比一次字符串本身

    优化: 不断计算hash不断对比, 这样两个hash值一样的时候不用再去计算剩余的哈希值.

    时间复杂度: O(n)

    # coding:utf-8
    
    
    
    class Rk(object):
        """
        字符串匹配: Rk算法, 借助hash算法实现
        此处假设只有字母和数字
        """
    
        def hash_func(self, string):
            """
            求string的ascii的和为hash函数
            :param string:
            :return:
            """
            return sum([ord(i) for i in string])
    
        def match(self, string1: str, string2: str):
            """
            :param string1: 主串
            :param string2: 模式串
            :return:
            """
            n = len(string1)
            m = len(string2)
            loop_nums = n - m + 1
    
            target_value = self.hash_func(string2)
    
            for i in range(loop_nums):
                tmp_string = string1[i:i + m]
                tmp_value = self.hash_func(tmp_string)
                if tmp_value == target_value:
                    # 防止hash冲突, 二次确认, 如果一致返回True
                    if tmp_string == string2:
                        break
            else:
                return False
            return True
    
    
    if __name__ == "__main__":
        bf = Rk()
        assert bf.match("abcabc", "ca") == True
        assert bf.match("abcabc", "bc") == True
        assert bf.match("abcabc", "cc") == False
        assert bf.match("abcabc", "cab") == True
        assert bf.match("abcabc", "cb") == False
    
    

    资料

    • 数据结构和算法 - 王争
  • 相关阅读:
    英语四级day1
    Hadoop实战
    Red Hat
    SQL Cookbook
    Java改错学习法
    Java程序设计经典300例
    Git
    ColorOS和MIUI双系统安装笔记
    深入浅出MySQL数据库开发、优化于管理维护
    剑指Offer名企面试官精讲典型编程题
  • 原文地址:https://www.cnblogs.com/zlone/p/11610677.html
Copyright © 2011-2022 走看看