在最后采访,面试官要求实现strstr(),当场就蒙了。
这个题目是模式匹配问题。《算法导论》里列出了几种字符串匹配算法:
朴素算法 | Rabin-Karp | 有限自己主动机算法 | Knuth-Morris-Pratt (KMP)
各种方法都有自己的优缺点,我认为,另一些方法能够參考:
1)比方像求最长公共子串那样,用动态规划。最后推断最长公共子串的最大值是不是模式串的长度,只是。这有点绕。
2)用后缀数组。这个也有点绕,实现起来也有点麻烦,就不说了。
个人认为。还是KMP好,KMP该怎么写呢,立刻抄起书《数据结构(C语言版)》,看了一下。感觉,KMP实现起来。代码是非常少的,效率还算能够了,实现的过程中,难就难在怎样构造next[] 数组。以及怎样理解next[]。对避免指针无效回退的作用。看了一个上午,总算是明确了。现就贴下代码,做下笔记。
#include<iostream> using namespace std; void get_next(const char* s, int* next){ int i = 0, j = -1; next[0] = -1; int len = strlen(s); while(i < len){ if(j == -1 || s[i] == s[j]){ ++i, ++j; if(s[i] != s[j]) next[i] = j; else next[i] = next[j]; } else j = next[j]; } } int KMP_strstr(const char* s, const char* p){ int i = 0, j = 0; int len_s = strlen(s), len_p = strlen(p); int* next = new int[len_p]; get_next(s, next); while(i < len_s && j < len_p){ if(j == -1 || s[i] == p[j]) ++i, ++j; else j = next[j]; } delete []next; if(j == len_p) return i - len_p; else return -1; } int main(){ const int len = 6; const char *s = "abaabc"; cout<<KMP_strstr("aaabbabaabcaad", s); return 0; }//output: 5
版权声明:本文博主原创文章,博客,未经同意不得转载。