诚城的成长 诚城的成长
首页
  • 高数基础
  • 数一

    • 高等数学
    • 线性代数
    • 概率论与数理统计
  • 820

    • 数据结构
    • 计算机操作系统
  • 英一

    • 单词
    • 语法
    • 阅读理解
    • 作文
  • 政治

    • 马克思主义基本原理
    • 毛泽东
    • 近代史
    • 思修
    • 时事
  • openpose
  • html5
  • css3
  • UI

    • Tailwind Css
    • Element-Plus
    • UniApp
  • 框架

    • Vue3
  • 拓展包

    • 包管理工具
    • 包开发
  • 开发语言

    • C语言
    • PHP
    • Phyton
  • 框架

    • Laravel
  • 会计

    • 初级经济法基础
    • 初级会计实务
  • 软考

    • 信息系统项目管理师
  • 博客

    • vitepress
    • vuepress
  • manim
  • git
  • vsCode
  • latex
  • docker
  • axios
  • vim
  • mac
  • Jetbrains

    • phpstorm
    • clion
突发奇想
GitHub (opens new window)

诚城

我有N个梦想……
首页
  • 高数基础
  • 数一

    • 高等数学
    • 线性代数
    • 概率论与数理统计
  • 820

    • 数据结构
    • 计算机操作系统
  • 英一

    • 单词
    • 语法
    • 阅读理解
    • 作文
  • 政治

    • 马克思主义基本原理
    • 毛泽东
    • 近代史
    • 思修
    • 时事
  • openpose
  • html5
  • css3
  • UI

    • Tailwind Css
    • Element-Plus
    • UniApp
  • 框架

    • Vue3
  • 拓展包

    • 包管理工具
    • 包开发
  • 开发语言

    • C语言
    • PHP
    • Phyton
  • 框架

    • Laravel
  • 会计

    • 初级经济法基础
    • 初级会计实务
  • 软考

    • 信息系统项目管理师
  • 博客

    • vitepress
    • vuepress
  • manim
  • git
  • vsCode
  • latex
  • docker
  • axios
  • vim
  • mac
  • Jetbrains

    • phpstorm
    • clion
突发奇想
GitHub (opens new window)
  • 绪论
  • 线性表

  • 栈队列数组

  • 串

    • 串 String
    • kmp
      • KMP
        • next 数组
        • KMP 比对
        • 字符串匹配实例
  • 树

  • 查找
  • 排序
  • 图
  • 数据结构
  • 串
诚城
2022-06-11
目录

kmp原创

# KMP

通过子串寻找规律,计算出 next 数组的值。同时支付串数组0下标依然存储字符串长度。

# next 数组

当前元素的前一个元素和一开始的元素相同出现的频次+1。

void get_next(char t[], int next[]){ // t为子字符串 
    int i=1,j=0; // i 记录子字符串的下标位置, j 记录子字符串对比的起始位置
    next[1]=0; // next 第二位 必须是 0
    while(i < t[0]){ // 子字符串的长度
        if( j == 0 || t[i] ==t[j]){ // t[i] ==t[j] 从子字符串中进行对比, j==0 子字符串又重头开始自我比对
            ++i;++j;
            next[i] = j; // next 记录出现重复的位置
        }else{
            j = next[j]; // 不相同时,将子字符串重新移动的位置
        }
    }
}

# KMP 比对

借助 next数组实现。

int KMP(char S[],char T[],int next[],int pos)
{
    int i=pos;//开始查找的起始位置
    int j=1;
    while(i<=S[0]&&j<=T[0])
    {
        if(j==0||S[i]==T[j]){//相等各自加加,往后走
            ++i;
            ++j;
        }
        else//不等,就回退next[j]的位置
            j=next[j];
    }
    if(j>T[0])//说明比对成功
        return i-T[0];
    else
        return 0;
}

# 字符串匹配实例

点击查看
#include <stdio.h>
#include <string.h>

typedef char* SString;

//int Index(SString s,SString t){
int Index(char *s,char *t){ // 同上等效
    int i=1,j=1;
    while(i <= s[0] && j<= t[0]){
        if(s[i] == t[j]){
            ++i,++j; // 继续比较后面的字符
        }else{
            i=i-j+2,j=1; //短字符串回到第一位,长字符串对比位置作相应的回调
        }
    }
    if(j>t[0]){ // 短字符串比较完
        return i-t[0]; //返回比对成功时长字符串的起始位置
    }else{
        return 0; // 短字符串未出现在长字符串中
    }
}

void get_next(char t[], int next[]){ // t为子字符串
    int i=1,j=0; // i 记录子字符串的下标位置, j 记录子字符串对比的起始位置
    next[1]=0; // next 第二位 必须是 0
    while(i < t[0]){ // 子字符串的长度
        if( j == 0 || t[i] ==t[j]){ // t[i] ==t[j] 从子字符串中进行对比, j==0 子字符串又重头开始自我比对
            ++i;++j;
            next[i] = j; // next 记录出现重复的位置
        }else{
            j = next[j]; // 不相同时,将子字符串重新移动的位置
        }
    }
}

int KMP(char S[],char T[],int next[],int pos)
{
    int i=pos;//开始查找的起始位置
    int j=1;
    while(i<=S[0]&&j<=T[0])
    {
        if(j==0||S[i]==T[j]){//相等各自加加,往后走
            ++i;
            ++j;
        }
        else//不等,就回退next[j]的位置
            j=next[j];
    }
    if(j>T[0])//说明比对成功
        return i-T[0];
    else
        return 0;
}

int KMPS(char S[],char T[],int pos=1)
{
    int i=pos;//开始查找的起始位置
    int j=1;
    while(i<=S[0]&&j<=T[0])
    {
        if(j==0||S[i]==T[j]){//相等各自加加,往后走
            ++i;
            ++j;
        }
        else{ //不等时继续往后对比
            i++;
            j=1;
        }

    }
    if(j>T[0])//说明比对成功
        return i-T[0];
    else
        return 0;
}

int main() {
    char S[256],T[10],P[10];
    int next[20];
    int pos;

    S[0]=strlen("abcabaaabaabcac"); // 字符数组第一位存储字符串长度
    strcpy(S+1,"abcabaaabaabcac");// 字符拼接
    T[0]=strlen("abaabc"); // 字符数组第一位存储字符串长度
    strcpy(T+1,"abaabc");// 字符拼接

    pos = Index(S,T); // 暴力匹配
    if(pos){
        printf("匹配成功,位置为长字符串的第%d位。\n",pos);
    }else{
        printf("未匹配到相关内容!\n");
    }

    get_next(T,next);//算出next数组

    pos=KMP(S,T,next,1);
    if(pos){
        printf("匹配成功,位置为长字符串的第%d位。\n",pos);
    }else{
        printf("未匹配到相关内容!\n");
    }

    return 0;
}

上次更新: 2022/08/23, 18:12:45
串 String
基础知识

← 串 String 基础知识→

Theme by Vdoing | Copyright © 2022-2022 carveybunt | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×
×

特别申明:

本站所有内容均为个人理解或转载,如有不当之处,敬请大佬指导!