首页 > 代码库 > LeetCode: Implement strStr() [027]
LeetCode: Implement strStr() [027]
【题目】
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
【题意】
实现库函数strStr(), 功能是在字符串haystack中找出目标串needle第一次出现的索引位
【思路】
字符串的匹配,可以用暴力解法,但不推荐。一般使用KMP算法求解。简要介绍一下KMP的思想:
haystack是题设所给的匹配串,needle是题设所给的模式串。
needle在和haystack匹配时,如果遇到某个位置上的字符失配,暴力法会将needle的游标返回头部,从头开始重新匹配;而KMP算法允许游标不返回头部,而利用已有的匹配结果,将游标移动到新的位置k上,从k位置开始匹配。如何确定这个新位置,或者说这个新位置是什么呢?
(1).我们这么来看,假设在当前的匹配过程中发现haystack[i]!=needle[j],显然这个时候haystack[i-j, i-1]和needle[0,j-1]各个位置上的字符已经匹配。
(2).此时,needle新的游标位置next[j]=k,它满足子串needle[0,k-1]与子串needle[j-k,j-1]完全匹配,也就是说字符串needle[0,j-1]的前k个字符与后k个字符相同。【k是满足该匹配条件的最大值,且k<j】
(3)把needle的游标从j移动到k,意味着我们从k开始比较就可以了,needle[0,k-1]不需要再重复比较了。这一点由(1)保证。
结合(1)(2)我们有:haystack[i-j, i-1]=needle[0,j-1] && needle[0,k-1]=needle[j-k, j-1]
显然我们可以推出:needle[0,k-1]=haystack[i-k,i-1]; 也即从k位置开始比较即可,不需要从头开始匹配。KMP算法关键在于建立next数组,即发生不匹配情况是回跳到哪个位置继续匹配。
假设我们已经确定了needle字符串中j位置的字符失配时跳转的位置是k,即next[j]=k, 根据上面的分析我们知道此时满足needle[0,k-1]=needle[j-k, j-1]。那next[j+1]=?
1. 如果needle[k]==needle[j],显然有needle[0,k]=needle[j-k, j],则next[j+1]=k+1;
2. 如果needle[k]!=needle[j], 这也是一种失配的情况(即needle起始字符串和结尾字符串匹配时发生失配),则游标k应该跳转到next[k],然后再与needle[j]比较,如果还是失配,游标继续通过next数组回跳,直至与needle[j]匹配,此时next[j+1]=k+1;
【代码】
class Solution { public: void getNext(char*needle, int*next){ int size=strlen(needle); int i=0,k=-1; next[0]=-1; while(i<size-1){ //因为我们通过A[i]来求A[i+1]的,因此结束条件是i<size-1 if(k==-1||needle[i]==needle[k]){ i++; k++; next[i]=k; } else{ k=next[k]; } } } char *strStr(char *haystack, char *needle) { if(needle==NULL || haystack==NULL)return NULL; int patternSize=strlen(needle); int haystackSize=strlen(haystack); int*next=new int[patternSize]; //生成next数组 getNext(needle,next); //匹配 int i=0; //haystack的游标 int j=0; //needle的游标 while(i<haystackSize&&j<patternSize){ if(j==-1||haystack[i]==needle[j]){ i++;j++; } else{ j=next[j]; } } delete next; if(j==patternSize)return haystack+i-j; return NULL; } };
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。