学习模式匹配有得
学会了模式匹配,能干的是有多了一件。
但是在学习过程中常用有问题的出现。
1、首先利用BF算法解决。
1 #include <cstring> 2 #include <iostream> 3 using namespace std; 4 #define MAXLEN 10000 5 6 //结构体定义 7 typedef struct 8 { 9 char ch[MAXLEN+1]; 10 int lenght; 11 }SString; 12 13 //因为忘记strlen()函数,所以自己写代码获取长度 14 void SetSString(SString &O) 15 { 16 O.ch[0] = '0'; //初始化 0 的下标 17 char ch[MAXLEN]; //输入数组 18 cin >> ch; 19 20 // 获取长度 21 int len = 0; 22 while(ch[len] != '\0') //赋值给定义的数组 23 { 24 O.ch[len+1] = ch[len]; 25 len++; 26 } 27 O.lenght = len; 28 } 29 30 int Index_BF(SString S, SString T, int pos) 31 { 32 int i = pos, j = 1; //i 为 主串, j为模式 33 34 // 开始匹配 35 while(i<=S.lenght && j<=T.lenght) 36 { 37 // 匹配成功 当前位置+1 38 if(S.ch[i] == T.ch[j]) 39 { 40 i++; 41 j++; 42 } 43 44 // 匹配不成功 主串回退到这次开始匹配时的位置+1,模式回退到第1个位置 45 else 46 { 47 i = i - j + 2; 48 j = 1; 49 } 50 } 51 52 // 判断是否完成匹配 53 if(j > T.lenght) 54 { 55 return i - T.lenght; 56 } 57 else return 0; 58 } 59 60 int main() 61 { 62 int pos = 1; //开始匹配位置 63 64 // 输入开始 65 SString S, T; 66 SetSString(S); 67 SetSString(T); 68 69 // 调用函数判断 70 if(Index_BF(S, T, pos) != 0) 71 { 72 cout << "successed"; 73 } 74 else cout << "falre"; 75 76 77 return 0; 78 }
从13行开始到28行是输入内容,我的想法是循环一遍输入,获取长度。但是,当MAXLEN定位10万级别时可以通过运行,达到100万时就会运行出错。这是我就想起栈空间很小,所以我把结构体改成堆空间存放。
1 typedef struct 2 { 3 char *ch; 4 int lenght; 5 }SString;
这样就不会出错了。
很明显我忘了一点——函数strlen(),所以我自己写函数获取字符串的长度。我上网查了一下strlen()的源码,发现只是很简单的几行。
1 int Strlen(const char * const s) 2 { 3 int i; 4 for (i = 0; s[i]; i++) ; 5 return i; 6 }
空循环体.....很有用的一个东西......什么都不干,只是定位到 '\0' 的下标,就是字符串的长度。
2、然后在写KMP算法时,因为之前打BF算法时忘记书本的内容,所以我很相信书本的例子,所说只是算法,但我加以修改使其变异不出问题即可。
1 int Index_KMP(SString S, SString T, int pos, int next[]) 2 { 3 int i = pos, j = 1; //i 为 主串, j为模式 4 5 // 循环开始 6 while(i<=S.lenght && j<=T.lenght) 7 { 8 if(S.ch[i] == T.ch[j]) 9 { 10 i++; 11 j++; 12 } 13 // 利用KMP算法 14 else 15 { 16 j = next[j]; 17 } 18 19 // 当模式回退到0位置时的处理 20 if(j == 0) 21 { 22 i++; 23 j++; 24 } 25 } 26 if(j > T.lenght) 27 { 28 return i - T.lenght; 29 } 30 else return 0; 31 }
书本上的代码是KMP算法代码是没有19到24行的,加上书上也没有说道当模式回退到0位置时要怎么操作,一时没有意识到这里要修改。所以在PTA上所有字母不匹配都会运行超时,后来再循环随意输出点东西就发现问题了。(最初我一直以为是我自己写的 获取字符串的长度的函数 有问题)
这次又学到了一点:有变量修改判断退出循环的一定要把所有的情况都考虑到,特别是 if.....else...语句 连续使用。
3、这次没有完成上一次的目标,怎么说呢,诸多原因,最主要的是和一道题较劲太久了,所以其他细节都没有处理,有些疑惑也没有深究。
下两周内,学好树与二叉树的同时,对于数组和广义表进一步深入学习。

浙公网安备 33010602011771号