• 《数据结构》之串的模式匹配算法——KMP算法


     1 //串的模式匹配算法
     2 //KMP算法,时间复杂度为O(n+m)
     3 #include <iostream>
     4 #include <string>
     5 #include <cstring>
     6 using namespace std;
     7 
     8 //-----串的定长顺序存储结构-----
     9 #define MAXLEN 255    //串的最大长度
    10 typedef struct {
    11     char ch[MAXLEN + 1];    //存储串的一维数组
    12     int length;    //串的当前长度
    13 }SString;
    14 
    15 int Next[MAXLEN + 1];
    16 int nextval[MAXLEN + 1];
    17 
    18 int Index_KMP1(SString S, SString T, int pos)
    19 {//利用模式串T的Next函数求T在主串S中的第pos个字符之后的位置
    20  //其中,T非空,1<=pos<=S.length
    21     int i = pos, j = 1;
    22     while (i <= S.length && j <= T.length)    //两个串均未比较到串尾
    23     {
    24         if (j == 0 || S.ch[i] == T.ch[j]) { ++i; ++j; }    //继续比较后继字符
    25         else j = Next[j];    //模式串向右移动
    26     }
    27     if (j > T.length) return i - T.length;    //匹配成功
    28     else return 0;    //匹配失败
    29 }
    30 
    31 int Index_KMP2(SString S, SString T, int pos)
    32 {
    33     int i = pos, j = 1;
    34     while (i <= S.length && j <= T.length)
    35     {
    36         if (j == 0 || S.ch[i] == T.ch[j]) { ++i; ++j; }
    37         else j = nextval[j];
    38     }
    39     if (j > T.length) return i - T.length;
    40     else return 0;
    41 }
    42 
    43 void get_next(SString T, int Next[])
    44 {//求模式串T的Next函数值并存入数组Next
    45     int i = 1, j = 0;
    46     Next[1] = 0;
    47     while (i < T.length)
    48     {
    49         if (j == 0 || T.ch[i] == T.ch[j]) { ++i; ++j; Next[i] = j; }
    50         else j = Next[j];
    51     }
    52 }
    53 
    54 void get_nextval(SString T, int nextval[])
    55 {//求模式串T的Next函数修正值并存入数组nextval
    56     int i = 1, j = 0;
    57     nextval[1] = 0;
    58     while (i < T.length)
    59     {
    60         if (j == 0 || T.ch[i] == T.ch[j])
    61         {
    62             ++i; ++j;
    63             if (T.ch[i] != T.ch[j]) nextval[i] = j;
    64             else nextval[i] = nextval[j];
    65         }
    66         else j = nextval[j];
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     SString A, B;
    73     A.ch[0] = B.ch[0] = ' ';
    74     while (scanf("%s%s", A.ch + 1, B.ch + 1) == 2)
    75     {
    76         A.length = strlen(A.ch + 1);
    77         B.length = strlen(B.ch + 1);
    78         get_next(B, Next);
    79         get_nextval(B, nextval);
    80         //修正之后匹配更快,结果相同
    81         int ans1 = Index_KMP1(A, B, 1), ans2 = Index_KMP2(A, B, 1);
    82         printf("%d	%d
    ", ans1, ans2);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    快速排序模板
    C++面试题目汇总
    二叉树两个节点的最大路径
    vim中操作的快捷键
    剑指offer 顺时针打印矩阵
    剑指offer 判断一棵树是不是另一棵树的子结构
    poi导出excel表
    java 获取服务器(ftp)指定文件夹内的文件
    部署web应用
    tomcat 的目录结构及修改端口号
  • 原文地址:https://www.cnblogs.com/jacen789/p/5349925.html
Copyright © 2020-2023  润新知