首页 > 编程语言 >字符串匹配算法

字符串匹配算法

时间:2022-10-15 23:23:28浏览次数:45  
标签:匹配 int text next char ++ 算法 str 字符串

#include <cstdio>
#include <cstring>

int brute_force(const char *text, const char *str) {
    for(int i = 0; text[i]; i++) {
        int miss_match = 0;
        for(int j = 0; str[j]; j++) {
            if(text[i + j] == str[j]) continue;
            miss_match = 1;
            break;
        }
        if(miss_match == 0) return i;
    }
    return -1;
}

//要在已成功匹对的字符串中找到真后缀与真前缀相等的最长情况,才能使得模式串移动位数最少(可通过假设模式串应移动1位,移动2位……一步一步归纳总结出该结论)
//next[j]记录了从下标0到下标j-1这一字符串中,使真后缀与真前缀相等时可以达到的最大长度
int kmp(const char *text, const char *str) {
    //1. init next
    //str[i-j]~str[i]是模式串的后缀,str[0]~str[j]是模式串的前缀
    int next[100] = {0};
    for(int i = 1, j = 0; str[i];) {
        while(j != 0 && str[j] != str[i]) { j = next[j]; }
        if(str[j] == str[i]) j++;
        next[++i] = j;
    }
    //2. match string
    //i是目标串的指针,j是模式串的指针
    for(int i = 0, j = 0; text[i]; i++) {
        while(j != 0 && str[j] != text[i]) { j = next[j]; }
        if(str[j] == text[i]) j++;
        if(str[j] == '\0') return (i + 1) - j; //此时j为模式串的长度
    } 
    return -1;
}

int sunday(const char *text, const char *str) {
    int len_text = strlen(text), len_str = strlen(str);
    int ind[128];
    for(int i = 0; i < 128; i++) ind[i] = len_str + 1; //若该字符从未出现的缺省距离
    for(int i = 0; str[i]; i++) ind[str[i]] = len_str - i; //该字符最后一次出现时到'\0'的距离
    int i = 0;
    while(i + len_str <= len_text) {
        int miss_match = 0;
        for(int j = 0; str[j]; j++) {
            if(text[i + j] == str[j]) continue;
            miss_match = 1;
            break;
        }
        if(miss_match == 0) return i;
        i += ind[text[i + len_str]]; //令模式串直接移动到能与“文本串中正对模式串'\0'的字符”进行匹对的位置
    }
    return -1;
}

int main() {
    char text[100], str[100];
    scanf("%s%s", text, str);
    printf("%d\n", brute_force(text, str));
    printf("%d\n", kmp(text, str));
    printf("%d\n", sunday(text, str));
    return 0;
}

总结:

  1. BF算法和sunday算法中的“i”总是指向模式串的第一个字符,所以是通过“i”来移动模式串的;
  2. 而KMP算法中的“i”则指向模式串中最长前缀的后一个字符,故KMP算法是通过减小“j”,同时令“j”与“i”对齐来移动模式串的。

标签:匹配,int,text,next,char,++,算法,str,字符串
From: https://www.cnblogs.com/Kelvin-Wu/p/16795338.html

相关文章

  • 多模匹配问题
    由来:KMP算法只能实现浏览一次目标串匹配一个模式串,而如果需要一次匹配多个模式串(即多模匹配问题),则需要更新原有的算法。Shift-And算法KMP算法的升级版:Shift-And算法Shif......
  • 十大经典排序算法复习
    十大经典排序算法复习转载文章:https://mp.weixin.qq.com/s/2_G89v9PR7g9O7U4cOdnKg10种经典排序算法:冒泡排序、选择排序、快速排序、归并排序、堆排序、插入排序、希尔......
  • 查找算法与哈希表
    三分查找应用场景:求下列一元二次函数的极大值\[ax^2+bx+c\]#include<stdio.h>intternary_search(int*arr,intl,intr){inttri,m1,m2;do{......
  • 排序算法
    内部排序:稳定排序(冒泡、插入、归并):重复的元素一定按原始顺序排列非稳定排序(选择、快排)外部排序:多路归并排序#include<stdio.h>#include<stdlib.h>#include<......
  • 比较排序算法概述
    文章目录​​排序​​​​ref​​​​排序的对象​​​​排序分类​​​​排序算法的稳定性SortAlgorithmStability​​​​性能分析​​​​比较排序算法的性能分析原则​......
  • 原来ShardingSphere也用雪花算法
    原来ShardingSphere也用雪花算法分布式主键的生成有很多实现方式,比如百度开源的UidGenerator、美团的Leaf、以及众所周知的雪花算法,而在分库分表的场景下,id要保证唯一性,分......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 19.删除链表的倒数第N个节
    24.两两交换链表中的节点本题是一道模拟过程的题目。搞清楚两两交换的步骤之后,写出对应的代码也就不是难题了。不过在学习题解的过程中发现,两两交换的步骤也有很多种实现......
  • 39.字符串类
    字符串类.cpp#pragmawarning(disable:4996)#define_CRT_SECURE_NO_WARNINGS1//2022年10月14日21:22:09#include<iostream>usingnamespacestd;#include"MyStrin......
  • 映射xml文件的数据库和实体类属性匹配问题
        实体类里和数据库里有些字段名匹配不上这就会导致即使成功连接数据库,但是由于不匹配的问题无法封装数据,这是在映射的xml文件里提供了一个方法来实现<resultMa......
  • AcWing 算法提高课 通过递推求等比数列的和(防止使用逆元出现问题)
    基于分治的思想:  例题:https://www.acwing.com/problem/content/99/模板:求num^0+num^1+...+num^kconstintMOD=9901;intQuickExp(intbase,intexp){bas......