Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
分析
模拟简单的正则匹配。'.'代表任意字符,'*'表示把前一个字符重复任意次(包括0次)。
比较麻烦的是这个'*'号,没有这个符号就很简单了,只要从头到尾比较就可以了。所以在第二个字符是'*'时,需要进行特殊处理。
最复杂的情况是,第二个字符是'*',且第一个字符还匹配。这时既要考虑到底是用第一个字符来匹配还是用后面的字符匹配。
就是说,要考虑下面两种情况:
1. s = "a" p = 'a*a'
2. s = "a" p = 'a*'
这两个case都应该匹配才对。
1 public class Solution { 2 public bool IsMatch(string s, string p) 3 { 4 if (string.IsNullOrEmpty(p)) 5 { 6 return string.IsNullOrEmpty(s); 7 } 8 9 if (!string.IsNullOrEmpty(s) && (s[0] == p[0] || p[0] == '.')) 10 { 11 if (p.Length > 1 && p[1] == '*') 12 { 13 return IsMatch(s.Substring(1), p) || IsMatch(s, p.Substring(2)); 14 } 15 else 16 { 17 return IsMatch(s.Substring(1), p.Substring(1)); 18 } 19 } 20 else 21 { 22 if (p.Length > 1 && p[1] == '*') 23 { 24 return IsMatch(s, p.Substring(2)); 25 } 26 else 27 { 28 return false; 29 } 30 } 31 } 32 }
PS. 因为字符串截取开销比较大,所以现在这个代码用时比较久,优化的方法是维护两个指针去遍历字符串,并缓存结果。但总体思路是一致的,就不再写了。
PPS. 题目中没提到表达式第一个就是'*'或者连续'*'的情况,这里也就没考虑直接submit试试,居然直接通过了。
后来自己写case发现跟答案是有出入的。看来实际的用例中是没有这种非法的输入值。果然像leetcode这样做得挺不错的题库也有一些考虑不到的情况。
不过我也就是写着玩玩不必较真啦:)