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).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aaa”,”aa”) → false
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
该题目的意思是,匹配两个字符串是否相等,其中'.'可以匹配任何字符,'*'前的字符可以匹配多次或者零次。
最开始我的想法是中规中矩的判断,逐个逐个位,按各种情况的去判断,但这样的方法在测试案例中有一个瓶颈,就是无法确定'*'前的字符应该匹配多少次,因为逐位去判断的话无法得知对后面字符匹配的影响,例如a*a分别与aaa和aaaa匹配,前者'*'前a应该匹配2次,后者应该匹配3次,但这中判断换成代码是十分复杂的,更别提如a*c*d*a与aaaa这些进一步复杂的情况,因此逐位判断是行不通的。后来参考网上的思路,发现普遍都是用递归的方法来做,这就很好的解决了这种情况,对于'*'前要匹配多少次,交给递归来尝试匹配与不匹配的情况就好了。
要利用递归的话首先得改变数据的类型,因为原题目isMatch(string s,string p)中使用string来处理的,这就使得递归的操作很难进行,因此得变成char *的类型,利用到char *a=s.c_str()这个转变的功能。
我的答案:
bool ismatch(const char *s, const char *p) {
if (*p == 0) { //p位空的情况
return (*s == 0);
}
if (*(p + 1) != '*') { //当前字符下一位不为'*'的情况
if ((*p == '.' || *p == *s)&&*s!=0)
return ismatch(s + 1, p + 1);
else
return false;
}
else { //当前字符下一位为'*'的情况
if ((*p != *s&&*p != '.')||(*s==0)) { //当前字符匹配0次
return ismatch(s, p + 2);
}
else { //分别判断当前字符是否匹配的影响
if (ismatch(s + 1, p))
return true;
else
return ismatch(s, p + 2);
}
}
}
class Solution {
public:
bool isMatch(string s, string p) {
const char *a = s.c_str(); //把string转变成const char *
const char *c = p.c_str();
return ismatch(a, c);
}
};