博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试经典--字符串匹配问题
阅读量:6071 次
发布时间:2019-06-20

本文共 2134 字,大约阅读时间需要 7 分钟。

字符串匹配问题描述:设有两个字符串A和B,A字符串长度为N,B字符串长度为M,现在要确定B字符串是否出现在A字符串中,如果是,返回位置,如果不是返回结果为false,在这里,我们成字符串B为模式字符串,A为主串。

最近经常会被问到字符串匹配的问题,实际上这些问题在网上都有很多资源,我觉得没有必要自己写一个,但是看了之后可能过段时间又不是很清楚了,因此在这里做个记录,记录那些让我感觉讲得比较清楚的主页。

1. KMP算法

KMP算法是O(M+N)的算法,KMP算法的思想很简单,那就是要利用之间比较的结果,其中有贪心算法和回溯算法的影子。此算法需要对模式字符串B进行预处理,得到一个长度与B相同的Partial数组()

  • 讲得比较明白浅显易懂的是: 只是一个简单的介绍
  • 讲得比较简洁清晰的是:  讲得很好,用C++实现了一下这个算法:
    #include 
    #include
    #include
    #include
    using namespace std; /*预处理的过程有人称之为求next数组,有人称之为求partial table 需要注意的是,next数组的长度不能是本身的长度,也就是说"aa"的next数组长度为1而不是2 不要问为什么,这个是由KMP算法的需求决定的 */ vector
    preprocessing(string & sub) {
    vector
    ret; if (sub.empty()) { return ret; } for(int i=0;i
    =0) { if(sub[forward]==sub[ret[backward]]) { ret[forward]=ret[backward]+1;break; } else { backward=ret[backward]-1; } } if(backward<0){ret[forward]=0;} } return ret; } bool isSubString(string & master ,string &sub,int &index) { if(master.length()
    P=preprocessing(sub); vector
    ::iterator int_iter; for(int_iter=P.begin();int_iter!=P.end();++int_iter) { cout<<*int_iter; } cout<
  • 讲得看来比较系统的是: ,这一篇我没来得及看,但是感觉排版稍微有些混乱
  • 2. BM算法

    通常情况下,BM算法要比KMP算法快3到5倍(好吧,这是别人总结的),这个在模式串越长的时候相对于KMP的优势越明显,维基百科上说,它的效率来自于这样的事实:对于每一次失败的匹配尝试,算法都能够使用这些信息来排除尽可能多的无法匹配的位置。由于每一次算法都给予好字符规则和坏字符规则确定最大的移位距离,所以虽然Boyer-Moore算法的执行时间同样线性依赖于被搜索字符串的大小,但是通常仅为其它算法的一小部分。但是目前为止我还无法描述算法复杂性。原始的BM算法最坏情况下的时间复杂度是O(MN),改进的BM算法改进的一般是预处理求好后缀规则和坏字符规则的方法。BM算法还有很多值得研究的地方,现在只是做个大概的总结,要研究透彻得看一看下面的第三个链接。

    • 同样讲得比较浅显易懂的是: 只是一个简单的介绍
    • 当然: 也是有的
    • 南柯一喵--  这个里面附带了一份BM代码,用KMP做预处理

    3.brute force

    蛮力算法,适合比较小规模的字符串匹配

    4.Rabin-Karp

    RK方法的设计思想也是利用前面已经获得的信息,该算法的思想是,通过对模式字符串进行hash运算,同时对源字符串取长度跟模式字符串相等的子字符串也进行hash运算,最后比较hash值来确定模式字符串是否和源字符串的子串匹配,并获得其匹配起始位置。问题的关键就在于hash算法的设计,里面是个比较易懂的描述。

     

    以上四种方法基本上概括了主流的字符串匹配算法,借用Robert Sedgewick 的Algorithm 一书中的一幅图总结一下,

     

    扩展:后缀树/后缀数组

    老实说,后缀树v_JULY_v也讲过,不过个人觉得字符串处理过程总才是个神器,而且也能够解决字符串匹配的问题,时间复杂度为O(M+logN)


    老实说,这都不太适合作为一篇博文发出,但是我今天看了的这些东西也不能够浪费,权且给下次看留点资源吧,等过段时间闲下来,我想写个字符串处理的专题,加油!!


    转载于:https://www.cnblogs.com/obama/archive/2013/05/06/3063771.html

    你可能感兴趣的文章
    Web实时通信技术
    查看>>
    第三章 计算机及服务器硬件组成结合企业运维场景 总结
    查看>>
    IntelliJ IDEA解决Tomcal启动报错
    查看>>
    默认虚拟主机设置
    查看>>
    七周五次课(1月26日)
    查看>>
    Linux系统一些系统查看指令
    查看>>
    php中的短标签 太坑人了
    查看>>
    [译] 可维护的 ETL:使管道更容易支持和扩展的技巧
    查看>>
    ### 继承 ###
    查看>>
    数组扩展方法之求和
    查看>>
    astah-professional-7_2_0安装
    查看>>
    函数是对象-有属性有方法
    查看>>
    uva 10107 - What is the Median?
    查看>>
    Linux下基本栈溢出攻击【转】
    查看>>
    c# 连等算式都在做什么
    查看>>
    使用c:forEach 控制5个换行
    查看>>
    java web轻量级开发面试教程摘录,java web面试技巧汇总,如何准备Spring MVC方面的面试...
    查看>>
    根据调试工具看Vue源码之组件通信(一)
    查看>>
    Thrift RPC 系列教程(5)—— 接口设计篇:struct & enum设计
    查看>>
    斯坦福-随机图模型-week1.5
    查看>>