• 串的模式匹配算法


    一,基本模式匹配算法

    #include<iostream>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str1[] = "abchelloefg";
        char str2[] = "hello";
        int i = 0, j = 0, flag = 0, len1 = strlen(str1), len2 = strlen(str2);
        for (i = 0; i < len1; i++){
            if (str1[i] == str2[j]){
                while (str1[i + j] == str2[j] && i + j < len1 && j < len2){
                    j++;
                }
                if (j == len2){
                    flag = 1;
                    break;
                }else if (i + j == len1){
                    flag = 0;
                    break;
                }else{
                    j = 0;
                }
            }
        }
        if (flag == 0){
            cout<<"无匹配字符串"<<endl;
        }else if (flag == 1){
            cout<<str1+i<<endl;
        }
        return 0;
    }
    View Code

    二,模式匹配的改进算法----KMP算法

    此算法的改进在于:每当一趟匹配过程中出现字符不等时,不需要回溯i指针,而是利用已经得到“部分匹配”的结果模式向右滑动尽可能远的一段距离后,继续进行比较。

    此算法需要求解next[]数组,此数组存放子字符串的一些值,将两个字符串比较原理用于一个字符串两部分比较。

    具体算法实现:

    #include <iostream>
    using namespace std;
    const int N = 100;
    
    void setNext(char *str, int len, int *next)
    {
        next[0] = -1;
        int i = 0, j = -1;
        while (i < len - 1) {
            if (j == -1 || str[i] == str[j]){
                i++;
                j++;
                next[i] = j;
            }else{
                j = next[j];
            }
        }
    }
    
    
    int main()
    {
        char str1[] = "abchelloefg", str2[] = "hello";
        int next[N], len1 = strlen(str1), len2 = strlen(str2);
        setNext(str2, len2, next);
        int i = 0, j = 0;
        while (i < len1 && j < len2){
            if (j == -1 || str1[i] == str2[j]){
                i++;
                j++;
            }else{
                j = next[j];
            }
        }
        if (j == len2){
            cout<<str1+i-len2<<endl;
        }else{
            cout<<"没有匹配的字符串"<<endl;
        }
        return 0;
    }
    View Code

     三,KMP算法的改进

    KMP算法中有一点不足之处是:当str1[i] != str2[j]时候,j = next[j];此时,如果str2[j] == str2[next[j]],则str1[i] != str2[next[j]],此时还需要将j = next[next[j]],进行测试。因此,我们再求next[]数组时候,提防这点:

    因此在求next[]数组时候,将代码:next[i] = j; 改为“

                if (str[i] == str[j]){
                    next[i] = next[j];
                }else{
                    next[i] = j;
                }

    具体代码:

    #include <iostream>
    using namespace std;
    const int N = 100;
    
    void setNext(char *str, int len, int *next)
    {
        next[0] = -1;
        int i = 0, j = -1;
        while (i < len - 1) {
            if (j == -1 || str[i] == str[j]){
                i++;
                j++;
                if (str[i] == str[j]){
                    next[i] = next[j];
                }else{
                    next[i] = j;
                }
            }else{
                j = next[j];
            }
        }
    }
    
    
    int main()
    {
        char str1[] = "abchelloefg", str2[] = "hello";
        int next[N], len1 = strlen(str1), len2 = strlen(str2);
        setNext(str2, len2, next);
        int i = 0, j = 0;
        while (i < len1 && j < len2){
            if (j == -1 || str1[i] == str2[j]){
                i++;
                j++;
            }else{
                j = next[j];
            }
        }
        if (j == len2){
            cout<<str1+i-len2<<endl;
        }else{
            cout<<"没有匹配的字符串"<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    第十四章 构建自定义的同步工具(待续)
    第十三章 显示锁(待续)
    第十二章 并发程序的测试(待续)
    第十一章 性能与可伸缩性(待续)
    第十章 避免活跃性危险(待续)
    第九章 图形用户界面的并行化(待续)
    第八章 线程池的使用(待续)
    第七章 取消与关闭(待续)
    NOIp 2015真题模拟赛 By cellur925
    [USACO10MAR]伟大的奶牛聚集Great Cow Gat…【树形dp】By cellur925
  • 原文地址:https://www.cnblogs.com/usa007lhy/p/3315655.html
Copyright © 2020-2023  润新知