字符串匹配算法


定义:在母串s中寻找是否有t 这个子串
母串s: a e c a e a e c a e d
模板串t: a e c a e d

暴力匹配

思路
将字符串s和字符串t进行匹配,一旦有失配字符,就将字符串t后移, 然后重新匹配,不断重复,直到匹配成功.

代码实现

int violen_match(const  char *s, const char *t) {
   
    for (int i = 0; s[i]; i++) {
   
        int flag = 1;
        for (int j = 0; t[j] && flag; j++) {
   
            flag = flag && (s[i + j] && s[i + j] == t[j]);
        }
        if (flag) return i;
    }
    return -1;
}

kmp

代码实现

int getNext(const char *t, int &j, char input, int *next) {
   
    while(j != -1 && t[j + 1] != input) j = next[j];
    if (t[j + 1] == input) j += 1;
    return j; 
    
}

int kmp(const char *s, const char *t) {
   
    int n = strlen(t);
    int *next = (int *)malloc(sizeof(int) * (n + 1));
    next[0] = -1;
    for (int i = 1, j = -1; t[i]; i++) next[i] = getNext(t, j, t[i], next);
    for (int i = 0, j = -1; s[i]; i++) {
   
        if (getNext(t, j, s[i], next) != n - 1) continue;
        return i - n + 1;
    }
    free(next);
    return -1;
}

sunday

思路
1.母串s:  a e c a e a e c a e d
模板串t:  a e c a e d
对字符串s和字符串t进行匹配,直到s的a字符和t的d字符失配.
母串s:    a e c a e a \color{#FF0000}{a} a e c a e d
模板串t: a e c a e d \color{#FF0000}{d} d

2.我们将字符串t后移一位得到
母串s:     a e c a e a e \color{#FF0000}{e} e c a e d
模板串t:     a e c a e d \color{#FF0000}{d} d

3. 移动一位以后,此时字符串s末尾的字符e和字符串t的末尾字符d不是同一字符,
我们需要将字符串t中字符e和字符串s的末尾字符移动到同一位置,t中的字符e在倒数第二个位置,因此我们需要将字符串t往后移动一位,得到
母串s:     a e c a e a e \color{#FF0000}{e} e c a e d
模板串t:        a e c a e \color{#FF0000}{e} e d

4.对齐后,我们重复1,发现a, c失配.
母串s:     a e c \color{#FF0000}{c} c a e a e c a e d
模板串t:        a \color{#FF0000}{a} a e c a e d

5.重复步骤2得到
母串s:     a e c a e a e c a \color{#FF0000}{a} a e d
模板串t:           a e c a e d \color{#FF0000}{d} d

6.重复步骤3得到
母串s:     a e c a e a e c a \color{#FF0000}{a} a e d
模板串t:                 a e c a \color{#FF0000}{a} a e d

7.对齐后在重复步骤1, 匹配成功

由此我们可知sunday匹配就是:
1.找到失配点;
2.然后移动一位找到黄金对齐点;
3.然后开始对齐(如果t中没有该字符,那么就移动到t的负一位,也就是移动整个字符串t,跳过该字符);
4.不断地重复&#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值