28.求子串出现的一个的位置

kmp

//复杂度O(n+m)
//求最大公共前后缀
#define SIZE 100
 
void calc_lcp(int* d, const char* p)
{
    //初始化,从一开始到最后。从0开始到最后第二个。求公共部分
    int i = 1, j = 0, np = strlen(p);
    //d[0]为0
    memset(d, 0, sizeof(int) * np);
    while (i < np)
    {
        //相等
        if (p[i] == p[j])
        {
            //d数组赋值,j是下标
            d[i++] = ++j;
        }
        //不相等
        else
        {
            //j大于0, 回溯再比较
            if (j > 0) j = d[j - 1];
            //j等于0,j无法移动了,只能i++
            else i++;
        }
    }
}
 
void kmp(const char* t, const char* p)
{
 
    int d[SIZE];
    //初始化参数
    int i = 0, j = 0, nt = strlen(t), np = strlen(p);
    //求最大公共前后缀
    calc_lcp(d, p);
    //边界:主串遍历完
    while (i < nt)
    {
        //相同
        if (t[i] == p[j])
        {
            i++, j++;
            //模式串遍历完
            if (j == np)
            {
                printf("%d\n", i - np);
                return;
            }
        }
        else
        {
            if (j > 0) j = d[j - 1];
            else i++;
        }
    }
 
    printf("%d\n", -1);
    return ;
 
}
 
int main(void)
{
    kmp("ABABABABC", "ABAB");
    kmp("ABABCABAB", "ABAB");
    kmp("AAAAAAA", "AAA");
    kmp("ABABABC", "ABABC");
    kmp("XYXZdeOXZZKWXYZ", "WXYZ");
    kmp("GCAATGCCTATGTGACCTATGTG", "TATGTG");
    kmp("AGATACGATATATAC", "ATATA");
    kmp("CATCGCGGAGAGTATAGCAGAGAG", "GCAGAGAG");
    return 0;
 
   
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值