leetcode之Implement strStr()

原题如下:

Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

典型的字符串匹配问题,才知道原来C语言里还有这样的方法可供调用,好了,说实现。实现可以采取两种思路,其中一种思路称之为简单或者暴力解法,即从头遍历,当发现不匹配时折返进行重新匹配。奇怪的是这个思路的时间复杂度时O(M*N)但在leetcode上没有出现超时问题。

 char *strStr1(char *haystack, char *needle) {
		int len1 = strlen(haystack);
		int len2 = strlen(needle);
		for(int i = 0; i <= len1 - len2; i++){
			char *p = haystack + i;
			char *q = needle;
			while(*q != '\0'){
				if(*p != *q)
					break;
				p++;
				q++;
			}
			if(*q == '\0')
				return p - len2;
		}
		return NULL;
    }

另外一种思路就是KMP解法了,这种解法在出现不匹配情况时不改变主串的位置,而是移动模式串,这样避免了一些无谓的比较。其比较过程如下:当模式串中第一个字符与主串不匹配或者模式串当前位置字符与主串字符匹配时,主串和模式串分别向后移动,当比匹配时,保持主串位置不变,而改变模式串的匹配位置j为当前节点的next[j]。从上述思路可以看出,KMP算法的关键是主串next[]的求解,而求解next的过程同样是一个模式串与自身的匹配问题,假设已知next[i] = j,那么如何求解next[i + 1]呢?这个问题分两种情况考虑:一是如果needle[i] == needle[j],那么next[i + 1] = j + 1,否则与上述匹配时的情况相同,让j = next[j].在求解next[]的过程中应该注意,当遇到next[j] = -1 时,其处理情况与匹配时的情况相同,都是next[++i] = ++j;,另外从该式也可以看出next[i +1]是由其前一个节点i的匹配情况决定的,所以遍历时不必遍历最后一个节点。

char *strStr(char *haystack, char *needle) {
		int len1 = strlen(haystack);
		int len2 = strlen(needle);
		vector<int>next(len2,-1);
		getNext(needle,next);		
		int i = 0, j = 0;
		while(i < len1 && j < len2){
			if(j == -1 || haystack[i] == needle[j]){
			    i++;
				j++;
			}
			else
			{
				j = next[j];
			}
		}
		if(j == len2)
			return haystack + (i - j);
		else
			return NULL;
	}
	void getNext(char *needle,vector<int>&next){
		int len = strlen(needle);
		int i = 0,j = -1;
		while(i < len - 1){			
		    if(j == -1 || needle[i] == needle[j]){
				next[++i] = ++j;				
			}
			else 
				j = next[j];
		}
	}

KMP算法关键是要理解思路,其代码具体实现并不复杂,要注意匹配算法和求next[] 算法的异同,同时要注意初值i和j的设定。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值