KMP算法

本文深入讲解了KMP算法的工作原理及实现过程,包括构建查询所用的dp数组和开始查询的具体步骤。通过Java和C++代码示例,详细阐述了KMP算法在字符串匹配中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 1.KMP算法看起来很像动规, 但又有区别
// 2.dp[M][256] : M表示走向的状态,256表示字符
// 3.base case : dp[0][pat[0]] = 1 
// 4.  1 表示已达当前状态 0 表示未达
// 5. 观察状态转移 time : O(256M) ~ O(M)
public class KMP {
	private int[][] dp;
	private String pat;
	
	// 构建查询所用的dp数组
	public KMP (String pat) {
		this.pat = pat;
		int M = pat.length();
		// dp[状态][字符] = 下个状态
		dp = new int[M][256];
		// base case
		dp[0][pat.charAt(0)] = 1;
		// 影子状态 X 初始为 0
		int X = 0;
		// 当前状态 j 从 1 开始
		for (int j = 1; j < M; j++) {
			for (int c = 0; c < 256; c++) {
				if (pat.charAt(j) == c) {
					dp[j][c] = j+1;
				} else {
					dp[j][c] = dp[X][c];
				}
			}
			// 更新影子状态
			X = dp[X][pat.charAt(j)];
		}
	}
	// 开始查询
	public int search(String txt) {
		int M = pat.length();
		int N = txt.length();
		// pat 的初始态为 0
		int j = 0;
		for (int i = 0; i < N; i++) {
			// 计算  pat 的下个状态
			j = dp[j][txt.charAt(i)];
			// 到达终止态,返回结果
			if (j == M) return i - M + 1;
		}
		// 没到达终止态,匹配失败
		return -1;
	}
}
// c++
void get_next() {
    next[0] = -1;
    int i = 0, j = -1;
    int len = strlen(pat);
    while(i < len) {
        if(j == -1 || pat[i] == pat[j])
            next[++i] = ++j;
         else j = next[j];
    }
}

bool KMP() {
    get_next();
    int len1 = strlen(pat);
    int len2 = strlen(s);
    int i = 0, j = 0;     // i 指向匹配串pat, j 指向主串s
    while(j < len2) {
        if(pat[i] == s[j]) {
            i++;
            j++;
            if(i == len1) return true;
        } else {
            i = next[i];
            if(i == -1) {
                j++;
                i++;
            }
        }
    }
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值