串的模式匹配

  1 #define _CRT_SUCURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #define N 255
  5 
  6 int Index_BF(char original[], char object[]);//Brute-Force返回值为0表示匹配失败
  7 int Index_KMP(char original[], char object[]);
  8 int* Get_Next(char object[]);
  9 int* Get_Nextval(char object[]);
 10 
 11 int main(void)
 12 {
 13     int pos;//模式串在主串的位置
 14     char original[N];
 15     char object[N];
 16 
 17     printf("请输入主串\n");
 18     gets_s(original);
 19     printf("请输入模式串\n");
 20     gets_s(object);
 21 
 22     if (0 == (pos = Index_BF(original, object)))
 23     {
 24         printf("\n匹配失败\n");
 25         exit(-1);
 26     }
 27     printf("(BF)模式串在主串的位置是:%d\n", pos);
 28 
 29     if ( 0 == (pos = Index_KMP(original, object)))
 30     {
 31         printf("\n匹配失败\n");
 32         exit(-1);
 33     }
 34     printf("(KMP_nextval)模式串在主串的位置是:%d\n", pos);
 35 
 36     system("pause");
 37     return 0;
 38 }
 39 
 40 int Index_BF(char original[], char object[])
 41 {
 42     int i = 0;
 43     int j = 0;
 44     int original_len = 0;
 45     int object_len = 0;
 46 
 47     while (original[++original_len] != '\0');
 48     while (object[++object_len] != '\0');
 49 
 50     if (original_len == 0 ||object_len == 0 || original_len < object_len)
 51     {
 52         printf("\n模式匹配参数不合法\n!");
 53         return 0;
 54     }
 55 
 56     while (i < original_len && j < object_len)
 57     {
 58         if (original[i] == object[j])
 59         {
 60             i++;
 61             j++;
 62         }
 63         else
 64         {
 65             i = i - j + 1;//主串回溯到 i - j + 1 的位置重新比较
 66             j = 0;//模式串重头开始比较
 67         }
 68     }
 69     if (j > object_len - 1)
 70     {
 71         return i - object_len + 1;
 72     }
 73     else
 74     {
 75         return 0;
 76     }
 77 }
 78 
 79 int Index_KMP(char original[], char object[])
 80 {
 81     int i = 0;
 82     int j = 0;
 83     int original_len = 0;
 84     int object_len = 0;
 85     int* next = Get_Next(object);
 86     int* nextval = Get_Nextval(object);
 87     while (original[++original_len] != '\0');//获得串长
 88     while (object[++object_len] != '\0');
 89 
 90     if (original_len < 0 || object_len < 0 || original_len < object_len)
 91     {
 92         printf("\n模式匹配参数不合法\n!");
 93         return 0;
 94     }
 95 
 96     while (i < original_len && j < object_len)
 97     {
 98         if (j == -1 || original[i] == object[j])//当 j == - 1时,进入循环加1。以保证 j 指向匹配串下标0的元素
 99         {
100             ++i;
101             ++j;
102         }
103         else
104         {
105             j = nextval[j];
106         }
107     }
108 
109     if (j > (object_len - 1))
110     {
111         return i - object_len + 1;
112     }
113     else
114     {
115         return 0;
116     }
117 }
118 
119 int* Get_Next(char object[])
120 {
121     int k = -1;
122     int j = 0;
123     int object_len = 0;
124     while (object[++object_len] != '\0');
125     int* next = (int*)calloc(object_len, sizeof(int));
126 
127     next[0] = -1;
128     while (j < object_len)
129     {
130         if (k == -1 || object[j] == object[k])
131         {
132             next[++j] = ++k;
133         }
134         else
135         {
136             k = next[k];
137         }
138     }
139     return next;
140 }
141 
142 int* Get_Nextval(char object[])
143 {
144     int j = 1;
145     int k = 0;
146     int object_len = 0;
147     int* next = Get_Next(object);
148     while ((object[++object_len]) != '\0');
149     int* nextval = (int*)calloc(object_len, sizeof(int));
150 
151     nextval[0] = -1;
152     while (j < object_len)
153     {
154         k = next[j];//k 是 模式串中第 j 个元素的最大滑动距离
155         if (object[j] == object[k])//模式串第  j 个元素和第 j - 1 个元素相同时
156         {
157             nextval[j] = nextval[k];//当模式串中第 j 个元素与主串对应元素失配,则第 j - 1 个元素也失配
158         }
159         else
160         {
161             nextval[j] = next[j];//模式串第  j 个元素和第 j - 1 个元素失配时
162         }
163         j++;
164     }
165     return nextval;
166 }

 

posted @ 2021-12-19 11:32  吕辉  阅读(75)  评论(0)    收藏  举报