KMP


title: KMP
date: 2020-10-27 00:27:16
tags: [KMP, AL, C语言, 算法, 数据结构, DS]
categories: DSandAL


KMP算法,代码写的不好看,也不简洁,自己手敲的,也算是开天辟地了

后续持续优化代码 + 思路详细讲解,只希望让后来者少踩坑,起码不要踩我踩过的坑 T^T

先附上代码,后续更新详细讲解

非递归求next数组
// 开始手写KMP   自我感觉还是不太好的
// 串的底层用静态数组实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef unsigned char str[MAX_SIZE];
int getLength(str);
int* getNext(str);

int main(void)
{
    str S = "dab5cdabcdabdebdedabcd1abdedabcd6abde";
    str T = "dabcdabde";
    int lengthT = getLength(T);
    printf("%d\n", lengthT);
    int lengthS = getLength(S);
    printf("%d\n", lengthS);
    int *next = getNext(T);
    // 打印next数组
    for (int i = 0; i < lengthT; i++)
        printf("%d ", next[i]);
    printf("\n");
    int i, j = 0, flag = 0;
    for (i = 0; i <= lengthS - lengthT;)
    {
        if (j == -1)
        {
            i++;
            j++;
        }
        while (T[j] && (S[i] == T[j]))
        {
            i++;
            j++;
        }
        if (j == lengthT)
        {
            flag = 1;
            break;
        }
        j = next[j];
    }
    if (flag)
        printf("%d", i - lengthT);
    else
        printf("找不到该子串\n");
    return 0;
}

int getLength(str T)
{
    int index = 0;
    while (T[index++])
        ;
    return index - 1;
}

int* getNext(str T)
{
    int length = getLength(T);
    int *next = (int *)malloc(sizeof(int) * length);
    // next数组的前两个
    next[0] = -1;
    next[1] = 0;
    for (int i = 2; i < length; i++)
    {
        // 当前字符的上一个字符的最大匹配数
        int k = next[i - 1];
        if (T[k] == T[i - 1])
            next[i] = k + 1;
        else
        {
            int flag = 1;
            while (next[k] != -1)
            {
                k = next[k];
                if (T[k] == T[i - 1])
                {
                    next[i] = k + 1;
                    flag = 0;
                    break;
                }
            }
            if (next[k] == -1 && flag)
                next[i] = 0;
        }
    }

    return next;
}
递归求next数组

递归中很多参数可以改成全局变量,本着把它封装成函数的目的,我没有设全局变量

确实挺浪费内存

// 手写KMP

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 100
// 定义字符串的数据类型
// 0号空间使用,配有长度
// 使用的是字符型指针,所以字符串的最后边不会被系统默认加上 '\0'
// 所以需要一个变量length来表示字符串的长度
typedef struct 
{
    char *str;
    int length;
}String;

int *getNextArr(String);
// 需要原来的next数组, 目标字符串, 当前求到第几个字符的next域了
void getEachValue(String, int*, int, int);
int main(void)
{
    String s, t;
    // 在这里,直接让它指向那块不可被修改的字符串的内存了
    // 后面还是有 '\0' 的
    s.str = "dab5cdabcdabdebdedabcd1abdedabcd6abde";
    s.length = strlen(s.str);
    t.str = "dabcdabde";
    t.length = strlen(t.str);
    // 求next数组
    int *next = getNextArr(t);
    // 打印next数组
    for (int i = 0; i < t.length; i++)
        printf("%d ", next[i]);
    printf("\n");
    return 0;
}

int *getNextArr(String s)
{
    int *next = (int *)malloc(sizeof(int) * s.length);
    next[0] = -1;
    next[1] = 0;
    for (int i = 2; i < s.length; i++)
        getEachValue(s, next, i - 1, i);
    return next;
}

void getEachValue(String s, int *next, int p, const int index)
{
    int k = next[p];
    if (k == -1)
        next[index] = 0;
    else if (s.str[index - 1] == s.str[k])
        next[index] = k + 1;
    else
        getEachValue(s, next, k, index);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值