• 串的匹配 (Brute - Force 算法)


    模式匹配

            • 设有主串 s 和子串  t , 子串 t 的定位就是要在主串 s 中找到一个与子串 t 相等的子串 . 

            • 通常我们把主串 s 称为目标串 , 把子串 t 称为模式串 , 定位也称作模式匹配

    ●模式匹配结果

            • 模式匹配成功 : 在目标串 s 中找到一个模式串 t

            • 模式匹配不成功 : 目标串 s 中不存在模式串 t

    例如 : 

            s : This is his hat . It is historical.

            t : his


    我们需要在 s 中找到 和 t 相同的串 的位置

    其实串的匹配问题 , 在生活中很常见

    比如 :

    ●网络安全:

            我们电脑里存放了一段病毒文件 , 我们不可能人工地去一个一个对比 , 这是很耗费时间的  , 我们需要拿着病毒文件 , 和 系统文件作对比 , 逐个去对比 ,找出病毒位置

    ●生物信息处理:

            侦破刑事案件的指纹识别 , 我们将犯罪嫌疑人的指纹 , 和提前录入数据库里面的指纹 , 进行匹配 . 帮助我们找到相应的犯罪嫌疑人的信息

    语音识别:

            语音识别 ,把语音转换成数字 ,和 数据库里面的语言代码进行匹配, 这些都涉及到串的匹配. 

    下面我们首先介绍一个最简单的算法 , 进行模式匹配  

    ● Brute - Force 算法

              • Brute - Force , BF 算法, 亦称简单匹配算法

             • 基本思路:

                    •  从目标串 s 第一个字符开始 和 模式串 t 的第一个字符比较  , 若相等 , 则继续逐个比较后续字符 

                    • 若不相等 , 则 从 s 的第二个字符 , 再次重新和模式串 t 第一个字符进行比较 ,

                    • 以此类推

                    • 若从 目标串 s 的第 i 个字符开始 , 每个字符依次和模式串 t 的对应字符相等 , 则匹配成功 , 返回 t  在 s 中的位置 i ; 否则 ,当我们遍历完了 串 s ,也没有匹配成功 , 代表匹配失败 ,函数返回 -1. 


    第一次比较:  逐个比较 ,比较到第四个字符 , 不符合 , 我们就把 串 t 往后移动对比  


     

     第二次 : 我们再次从 t 开始和 s 的第二个字符匹配对比 , 比较到 t 的第四个字符 , 不符合 , 串t

    继续 和 s 的第三个字符开始比较


     第三次 :  我们逐个比较 s 和 t 字符 , 匹配成功 , 返回 串 t 第一个字符 在 s 中的位置


    上面是机器的模拟对比 , 我们可以拿两个纸片 , s固定 , 拿着 t ,从开头开始对比 , 不匹配,就后移一位 , 然后 再进行对比匹配 

    下面进行代码实操 :

    设置两个串  s  和  t

     


    逐个进行对比 , 如果不同,则 串 t 向后移动 , 从串 t 开头和 串 s 第二个元素对齐,逐个遍历 ,总能找出答案 , 符合,或者不符合

     假如前四个有一个不符合 , 就从串 s 的第二个元素开始 ,和 串 t 进行逐个对比 , 以此类推



    如果 , 串 t 的指针位序 ,能达到 串 t 的长度,则代表已经找到符合的串 ,跳出

    如果 , 串 s 已经遍历完了 ,则也跳出 , 表示无符合的子串 

    1. //传入两个串 s 和 t
    2. int index(SqString s , SqString t)
    3. {
    4. //下面我们定义, 每次开始重新对比时, 指向两个串的指针
    5. //初始都是0
    6. int i=0; //指向 s 串每次开始对比的位序
    7. int i_1 = 0; //每次对比 ,串 s 的计数器
    8. int j = 0; //指向 t 串每次对比的位序
    9. //开始循环对比
    10. while((i+i_1)
    11. {
    12. //此时的 i ,j ,是初始的指针,我们还可以当作计数器, 来指向串元素
    13. //如果串 s 第i个元素 和 串 t 第 j 个元素相等, 则继续比较下一个
    14. if(s.data[i+i_1] == t.data[j])
    15. {
    16. i_1++;
    17. j++;
    18. }
    19. //如果不相同,就像我们图示那样, 串 s 重新开始对比的数组位序加一
    20. //此时串 t 也需要重新进行对比,计数器也置成0
    21. else
    22. {
    23. i++;
    24. j=0;
    25. }
    26. }
    27. //当我们的 j>=s.length的时候,跳出的时候,说明我们的串 t 已经判断完了,找到了符合的子串
    28. //我们返回其在串 s 中,刚开始的位序就行了
    29. if(j>=t.length)
    30. {
    31. //我们的 i ,就是每次重新遍历的 串 s的位序
    32. return (i);
    33. }
    34. else
    35. {
    36. //找不到或找不齐返回-1,表示没找到
    37. return (-1);
    38. }
    39. }

    ● 算法分析

    • 最好情况复杂度: O(m)
            •目标串的前 m 个字符正好等于模式串的m个字符
        • 最坏情况复杂度 : O(n*m)
            • 每次到最后一个字符,才发现不匹配,这时再倒回去
                进行比较
            • 计数关系 : m*(n-m)

    ● 算法评价

    • 这个算法简单 , 易于理解,但效率不高
        • 当m 小于 5时, 几乎是最好的,但是数字越多,复杂度剧增

    ● 算法的改进方案

    ● 为什么我们感觉复杂度增加 
            •因为我们每次都是匹配到不同的字符 ,都是对串 s 的开始字符,进行逐步加一,然后再让s和 t 进行从头对比
        ● 有些情况, 我们串 t 的每个字符都不相同, 我们对比之后 , 这一串对比的,就应该抛弃了,
            串s开始比较的字符就应该跳过 t的字符串长度的字符 ,
            再进行重新比较,我们下一步针对这个问题进行具体分析

  • 相关阅读:
    vue3验证码倒计时60秒(自用)
    【sdk】- 对接阿里云抠图
    Java 23种设计模式分类概括以及应用介绍
    删除的视频怎么找回来呢?
    LeetCode|股票问题|121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II、123. 买卖股票的最佳时机 III
    QT学习管理系统
    一文看懂混沌网格(Chaos Mesh)工作原理
    深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
    单词~~~~~
    SpringBoot+Vue实现前后端的毕业设计管理系统
  • 原文地址:https://blog.csdn.net/qq_57484399/article/details/127546413