Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
题意:判断一个字符是否在另一个中,若是,则返回第一次出现时的地点,若不是,则返回NULL;
思路:常规的思路是,暴力解法。在文本串中,找到模式串第一次出现的位置。从左往右遍历文本串和模式串,若当前字符对匹配,则比较下一对,若是不匹配,则,文本串中字符向右移动一位,而模式串中的字符回到首字母重新和文本串中的字符比较,重复上述,直到找到或者跳出。假设文本串为:abcedefgh,模式串为:ef,开始时,a-e不匹配,所以,比较b-e,发现还是不匹配,直到e-e,然后比较文本串中的d和模式串中的f,发现不匹配,所以,文本串中右移一位到第二个e,而模式串中则回到首字符e,两者重新比较。所以每次的比匹配,都需要重新从模式串中的首字符开始,而文本串中则从当前位置的下一位开始。
这过程中就遇到一个问题了,如何在文本串中移动的问题?如在文本串中当index=3时,首字符匹配了,i是否继续移动?若是继续移动,要是这点是两字符匹配的起点,如何返回这点,还有就是,如不是,i已经移动了,如何返回到index=3的下一点,即index=4这点重新开始比较?所以这里采用的是haystack[i+j] !=needle[j],这种方式进行比较,当然也可以通过i-=j-1;j=0;的方式进行。
另一个问题是,因为跳出内层for循环有两个原因,一、不匹配,二、匹配;所以这里还得给出判断,找到跳出原因。
方法一:玻璃解法,代码如下:
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) 4 { 5 int lenHay=strlen(haystack),i=0; 6 int lenNeed=strlen(needle),j=0; 7 8 if(lenNeed>lenHay) return NULL; 9 if(lenNeed==0||lenHay==0) return haystack; 10 11 for(;i<lenHay-lenNeed+1;++i) 12 { 13 for(j=0;j<lenNeed;++j) 14 { 15 if(haystack[i+j] !=needle[j]) 16 break; 17 } 18 if(j>=lenNeed) 19 break; 20 } 21 return (j>=lenNeed)?&haystack[i]:NULL; 22 } 23 };
方法二:使用KMP算法,具体分析过程见博客KMP算法详解代码如下:
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) 4 { 5 int n=strlen(haystack),i=0; 6 int m=strlen(needle),j=0; 7 8 if(m>n) return NULL; 9 if(n==0||m==0) return haystack; 10 11 vector<int> next(m); 12 getNext(needle,m,next); 13 14 while(j<m&&i<n) 15 { 16 if((0>j||haystack[i]==needle[j])) 17 { 18 i++; 19 j++; 20 } 21 else 22 j=next[j]; 23 } 24 return j==m?&haystack[i-j]:NULL; 25 } 26 27 vector<int> getNext(char *needle,int m,vector<int> &next) 28 { 29 int t=-1; 30 next[0]=-1; 31 int j=0; 32 while(j<m-1) 33 { 34 if(0>t||needle[j]==needle[t]) 35 { 36 j++; 37 t++; 38 next[j]=(needle[j] !=needle[t]?t:next[t]); 39 } 40 else 41 t=next[t]; 42 } 43 return next; 44 } 45 };