千家信息网

如何使用java暴力匹配及KMP算法解决字符串匹配问题

发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,这篇文章主要介绍如何使用java暴力匹配及KMP算法解决字符串匹配问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!要解决的问题?一、暴力匹配算法一个图例介绍KMP算法Stri
千家信息网最后更新 2025年11月13日如何使用java暴力匹配及KMP算法解决字符串匹配问题

这篇文章主要介绍如何使用java暴力匹配及KMP算法解决字符串匹配问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

要解决的问题?

一、暴力匹配算法

一个图例介绍KMP算法

String str1 = "BBC ABCDAB ABCDABCDABDE";String str2 = "ABCDABD";

1. S[0]为B,P[0]为A,不匹配,执行第②条指令:"如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0",S[1]跟P[0]匹配,相当于模式串要往右移动一位(i=1,j=0)

2. S[1]跟P[0]还是不匹配,继续执行第②条指令:"如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0",S[2]跟P[0]匹配(i=2,j=0),从而模式串不断的向右移动一位(不断的执行"令i = i - (j - 1),j = 0",i从2变到4,j一直为0)

3. 直到S[4]跟P[0]匹配成功(i=4,j=0),此时按照上面的暴力匹配算法的思路,转而执行第①条指令:"如果当前字符匹配成功(即S[i] == P[j]),则i++,j++",可得S[i]为S[5],P[j]为P[1],即接下来S[5]跟P[1]匹配(i=5,j=1)

4. S[5]跟P[1]匹配成功,继续执行第①条指令:"如果当前字符匹配成功(即S[i] == P[j]),则i++,j++",得到S[6]跟P[2]匹配(i=6,j=2),如此进行下去

5. 直到S[10]为空格字符,P[6]为字符D(i=10,j=6),因为不匹配,重新执行第②条指令:"如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0",相当于S[5]跟P[0]匹配(i=5,j=0)

6. 至此,我们可以看到,如果按照暴力匹配算法的思路,尽管之前文本串和模式串已经分别匹配到了S[9]、P[5],但因为S[10]跟P[6]不匹配,所以文本串回溯到S[5],模式串回溯到P[0],从而让S[5]跟P[0]匹配。

而S[5]肯定跟P[0]失配。为什么呢?因为在之前第4步匹配中,我们已经得知S[5] = P[1] = B,而P[0] = A,即P[1] != P[0],故S[5]必定不等于P[0],所以回溯过去必然会导致失配。那有没有一种算法,让i 不往回退,只需要移动j 即可呢?

答案是肯定的。这种算法就是KMP算法,它利用之前已经部分匹配这个有效信息,保持i 不回溯,通过修改j 的位置,让模式串尽量地移动到有效的位置。

public class ViolenceMatch {        public static void main(String[] args) {                String str1 = "硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好";                String str2 = "尚硅谷你尚硅你";                int index = violenceMatch(str1, str2);                System.out.println("index=" + index);        }        /**         * 暴力匹配算法         */        public static int violenceMatch(String str1, String str2) {                char[] s1 = str1.toCharArray();                char[] s2 = str2.toCharArray();                 int s1Len = s1.length;                int s2Len = s2.length;                 int i = 0;// i索引指向s1                int j = 0;// j索引指向s2                while (i < s1Len && j < s2Len) {// 保证匹配时,不越界                        if (s1[i] == s2[j]) {// 匹配ok                                i++;                                j++;                        } else {// 没有匹配成功                                        // 如果不匹配(即str1[i] != str2[j],令i = i - (j - 1),j = 0)                                i = i - (j - 1);                                j = 0;                        }                }                // 判断是否匹配成功                if (j == s2Len) {                        return i - j;                } else {                        return -1;                }        }}

暴力匹配算法的缺点:大量数据使用暴力匹配效率很低

二、KMP算法

关于KMP算法的学习,参考了这篇文章,此博主写的特别详细,大佬!

很详尽KMP算法(厉害) - ZzUuOo666 - 博客园

算法介绍

KMP的主要思想是:1. 先得到子串的部分匹配表 2.使用部分匹配表完成KMP匹配

一个图例介绍KMP算法

代码实现

public class KMPAlgorithm {        public static void main(String[] args) {                String str1 = "BBC ABCDAB ABCDABCDABDE";                String str2 = "ABCDABD";                int[] next = kmpNext("ABCDABD");                System.out.println("next=" + Arrays.toString(next));           int index = kmpSearch(str1, str2, next);                System.out.println("index=" + index);        }         /**         * kmp搜索算法         *          * @param str1 原字符串         * @param str2 子串         * @param next 部分匹配表,是子串对应的部分匹配表         * @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置         */        public static int kmpSearch(String str1, String str2, int[] next) {                // 遍历                for (int i = 0, j = 0; i < str1.length(); i++) {                         // 需要处理 str1.charAt(i) != str2.charAt(j),去调整j的大小                        // KMP算法核心点                        while (j > 0 && str1.charAt(i) != str2.charAt(j)) {                                j = next[j - 1];                        }                        if (str1.charAt(i) == str2.charAt(j)) {                                j++;                        }                        if (j == str2.length()) {// 找到了                                return i - j + 1;                        }                }                return -1;        }         /**         * 获取到一个字符串(子串)的部分匹配值表         */        public static int[] kmpNext(String dest) {                // 创建一个next数组保存部分匹配值                int[] next = new int[dest.length()];                next[0] = 0;// 如果字符串是长度为1部分匹配值就是0                for (int i = 1, j = 0; i < dest.length(); i++) {                        // 当dest.charAt(i) != dest.charAt(j),需要从next[j - 1]获取新的j                        // 直到发现有dest.charAt(i) == dest.charAt(j)成立才退出                        // 这是kmp算法核心点                        while (j > 0 && dest.charAt(i) != dest.charAt(j)) {                                j = next[j - 1];                        }                        if (dest.charAt(i) == dest.charAt(j)) {                                j++;                        }                        next[i] = j;                }                return next;        }}

以上是"如何使用java暴力匹配及KMP算法解决字符串匹配问题"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

算法 字符 暴力 部分 成功 字符串 失配 指令 模式 硅谷 移动 问题 位置 就是 篇文章 有效 不断 内容 图例 思路 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 IT网络安全运维soc 网络安全态势感知宣传稿脚本 国际与国内软件开发策略 数据库安全性常见策略 香港服务器怎么连接矿池 后台数据库设计存储用户相关信息 ftp服务器 安全防范 php读取数据库信息到前台 云南宣威网络安全检查 网络安全法两个重点方面是 信息化软件开发报价表 我的世界启动器为什么玩不了服务器 闵行区管理软件开发厂家报价 学网络安全找不到工作 网络安全技术论坛开场白主持稿 数据库专业面试问题吗 网络安全治安管理方案 萤石云视频怎么重新连接服务器 学校网络安全项目预期效益 中专上计算机网络技术怎么样 小学生网络安全实践活动 通过sql语句生成数据库 cfd软件开发方案 对于网络安全的建议意见 长沙网律互联网科技的限公司 服务器一般没有显卡吗 数据库群集工作流程 数据库系统原理A并B 南京网络安全厂商 全球最先进网络技术
0