zoukankan      html  css  js  c++  java
  • 数据结构之串的匹配

    串的匹配应用十分广泛,比如搜索引擎、拼写检查、语言翻译、数据压缩等等,都需要进行串的匹配。

    串的模式匹配设有两个字符串 S 和 T ,设 S 为主串(正文串),T 为子串(模式),在主串 S 中查找与模式 T 相匹配的子串,如果匹配成功,确定相匹配的子串中第一个字符在主串 S 中出现位置。下面介绍两种算法:BF 算法和 KMP 算法。

    一、BF算法

    1、分别利用计数指针 i 和 j 指示主串 S 和 模式 T 中当前待比较的字符位置。
    2、如果比较未到结尾,则循环执行以下操作:
    ① S.ch[ i ] 和 T.ch[ j ] 比较,若相等,则 i++; j++; 继续比较后续字符。
    ② 若不等,指针后退重新匹配,从主串的下一个字符(i = i - j + 2)起再重新和模式的第一个字符(j = 1)比较。
    3、如果 j > T.length,说明匹配成功,返回和模式 T 第一个字符相等的字符在主串中的序号(i - T.length),否则失败,返回0。

    该算法的时间复杂度为 O(m × n)

    代码如下:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #define MAXSIZE 20
     5 typedef struct
     6 { // 定义数组存储字符串
     7     char ch[MAXSIZE+1];
     8     int length;
     9 }String;
    10 int index_BF(String S, String T);
    11 int main()
    12 {
    13     int flag;
    14     String S, T;
    15     printf("请输入主串S:");
    16     gets(S.ch + 1);
    17     S.length = strlen(S.ch+1);
    18     S.ch[0] = (char)S.length;
    19     printf("请输入模式串T:");
    20     gets(T.ch + 1);
    21     T.length = strlen(T.ch+1);
    22     T.ch[0] = (char)T.length;
    23     flag = index_BF(S, T);
    24     if (flag)
    25         printf("匹配成功,在第%d位。
    ", flag);
    26     else
    27         printf("匹配失败,未找到该子串。
    ");
    28 }
    29 int index_BF(String S, String T)  // BF算法
    30 {
    31     int i = 1,j = 1;
    32     while (i <= S.length && j <= T.length) // 两串均未到达串尾
    33     {
    34         if (S.ch[i] == T.ch[j]) { i++; j++; } // 继续向后匹配字符
    35         else { i = i - j + 2; j = 1;}  // 若不相等,回溯
    36     }
    37     if (j > T.length)
    38         return i - T.length;
    39     else
    40         return 0;
    41 }

    效果如下:

    运行结果

    二、KMP算法

    此算法的改进在于,每当每当匹配过程中出现字符比较不相等时,不需要回溯 i 指针,而是利用已经得到的 “部分匹配” 的结果将模式向右 “滑动” 尽可能远的一段距离,继续进行比较。而滑动的具体距离,由 get_next 函数确定,具体原理不再描述。

    时间复杂度为 O(m + n),较BF算法有很大提升。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #define MAXSIZE 20
     5 typedef struct
     6 { // 定义数组存储字符串
     7     char ch[MAXSIZE + 1];
     8     int length;
     9 }String;
    10 int index_KMP(String S, String T, int next[]);
    11 void get_next(String T, int next[]);
    12 int main()
    13 {
    14     int flag;
    15     int next[MAXSIZE] = {0};
    16     String S, T;
    17     printf("请输入主串S:");
    18     gets(S.ch + 1);
    19     S.length = strlen(S.ch + 1);
    20     S.ch[0] = (char)S.length;
    21     printf("请输入模式串T:");
    22     gets(T.ch + 1);
    23     T.length = strlen(T.ch + 1);
    24     T.ch[0] = (char)T.length;
    25     get_next(T, next);
    26     flag = index_KMP(S, T, next);
    27     if (flag)
    28         printf("匹配成功,在第%d位。
    ", flag);
    29     else
    30         printf("匹配失败,未找到该子串。
    ");
    31 }
    32 void get_next(String T, int next[])
    33 {
    34     int j = 0, i = 1;
    35     next[1] = 0;
    36     while (i < T.length)
    37     {
    38         if (j==0 || T.ch[i] == T.ch[j]) { i++; j++; next[i] = j; }
    39         else j = next[j];
    40     }
    41 }
    42 int index_KMP(String S, String T, int next[])
    43 {
    44     int i = 1, j = 0;
    45     while (i <= S.length && j <= T.length)
    46     {
    47         if (j == 0 || S.ch[i] == T.ch[j]) { i++; j++; }
    48         else j = next[j];
    49     }
    50     if (j > T.length)
    51         return i - T.length;
    52     else
    53         return 0;
    54 }

    效果如下:

    在这里插入图片描述

    以上就是两种最常用的串匹配算法

  • 相关阅读:
    sql server 存储过程分隔split
    sql server 存储过程、事务,增删改
    jquery ajax 参数可以序列化
    Pycharm连接gitlab
    gitlab的搭建和linux客户端的连接
    jenkins的搭建和使用
    svn服务器及客户端安装使用
    python2 和python3共存下问题
    Codecademy For Python学习笔记
    类编写的细节
  • 原文地址:https://www.cnblogs.com/yytest/p/12528168.html
Copyright © 2011-2022 走看看