LeetCode之Regular Expression Match的js实现

题目在这里

简单翻译一下。就是实现这样一个正则表达式,支持'*'和'.'。

'*'不能单独出现,它之前必须有一个字符可以是a-z或者'.'。

'*'表示重复它之前的字母n次(n>=0)

'.'表示可以充当a-z的任意一个字符。

举几个例子:

1、

Input:
s = "aa" 
p = "a"
Output: false
解释: "a" 不能完全匹配 "aa".
2、
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*'重复a一次,这样变成aa,能和s匹配.
3、
Input:
s = "ab"
p = ".*"
Output: true
Explanation: "*" 重复'.'一次,变为..,..可匹配ab".
4、
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c重复0次,a重复1次,变为aab,可以和s匹配。

下面讲下实现思路。

举例子说明吧:

假设s = "misissippppi",p="a*b*mis*sis*ip*i",s的指针称为i,p的指针称为j。

s[0] = 'm',p[0] = 'a',p[1] = '*',m和a不能匹配,并且p[1] = '*',这时候要跳过'a*'这个字符串向前匹配,也就是i=0,j = j+2(j=2)。

s[0] = 'm',p[2] = 'b',p[3] = '*'  m和b不能匹配,并且p[3] = '*',这时候要跳过'b*'这个字符串向前匹配,也就是i=0,j = j+2(j=4)。

s[0] = 'm',p[4] = 'm',并且p[5] != '*',能匹配成功,i=i+1(i=1),j=j+1(j=5),继续匹配

... ...

s[2] = 's',p[6] = 's',并且p[7] == '*',因为此时不能确定's'要重复多少次,所以要测试,我们先假设重复0次,看s2和p[8]能不能匹配,如果能匹配,说明重复0次成功,如果不能匹配,i++,继续匹配。如果指针越界都没匹配成功,说明匹配失败,直接返回false。

完整的代码如下:

function myMatch(s,p,i,j){
	if(j >= p.length){ //如果p的指针已经移出结尾,看s的指针,如果s的指针也移出结尾,返回匹配成功,否则匹配失败
	   return i >= s.length;
	}
	if(j == p.length-1){ //如果p的指针指向最后一位,那直接和s的最后一位比较即可,而且这里的的最后一位不可能是*号,因为如果是*,下面的代码会把*跳过
	   return (i == s.length -1) && (p.charAt(j) == s.charAt(i) || p.charAt(j) == '.')
	}

	if(j+1 < p.length && p[j+1] != '*'){//如果j+1不是*
	  if(p[j] == s[i] || p[j] == '.'){ //并且和s能匹配上
	  	  return myMatch(s,p,i+1,j+1); //看下一位能不能匹配上
	  }
	  return false;
	}
	with(j < p.length && i < s.length && (p[j] == s[i]) || p[j] == '.'){ //如果j+1是*,并且能匹配成功
		if(myMatch(s,p,i,j+2)){ //假设*号重复它前面的字符0,1,2,3,4...次,测试成功一次即可
		   return true;
		}
		i++;
	}
	return myMatch(s,p,i,j+2); //如果j+1是*,并且不能匹配成功,跳过这个x*这两个字符
}
var ss = "mississippppi";
var pp = "a*b*mis*is*ip*i";
console.log(myMatch(ss,pp,ss.length-1,pp.length-1));

这里需要注意的是这段代码的一个边界问题:

if(myMatch(s,p,i,j+2)){ //假设*号重复它前面的字符0,1,2,3,4...次,测试成功一次即可
		   return true;
		}

举个例子:

s = abc;

p= a*abc;

因为s[0]和p[0]匹配成功,p[1]是'*',所以如果认为s[0]和p[0]是匹配成功的,那么接下来结果肯定是匹配失败,因为这里s[0]要和p[2]匹配才能保证最终结果匹配成功。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值