[Leetcode] Implement strstr
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 };
[Leetcode] Implement strstr