剑指Offer-52.正则表达式匹配(C++/Java)
题目:
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
分析:
我们先分析匹配时,模式中的字符的下一个是*的情况,此时还会分成两种情况,
一种是当前字符串中的字符和模式中的字符相同,或者模式中的字符是‘.’,也就是a和a* 或者 a和.*,此时我们有三条策略继续匹配,
一种是认为a后面可能还有a,也就是*代表多个字符,所以匹配字符串字符的下一个字符和当前模式的字符。
一种是认为a已经可以和当前模式的字符匹配上了,也就是*认为是1个字符,所以匹配字符串字符的下一个字符和当前模式的字符的下两个(a*匹配成功)。
或者是将*当成0个字符,所以匹配字符串的当前字符和当前模式的字符的下两个(a*和空字符匹配成功)。
这三种情况的结果取或,因为有一种匹配成功,就算匹配了。b
如果前字符串中的字符和模式中的字符不相同,也就是(a和b*)这种情况,那么就匹配字符串的当前字符和当前模式的字符的下两个(b*和空字符匹配成功)。
如果模式中的字符的下一个不是*,也会分两种情况。
一种是当前字符串中的字符和模式中的字符相同或模式中的字符是‘.’,也就是a和a或a和.这种,我们可以直接去匹配字符串和模式字符串的下一个字符。
另一种情况就是当前的字符是不同的,那么就直接返回错误即可。
注意java要时刻判断数组越界问题。
程序:
C++
class Solution { public: bool match(char* str, char* pattern) { if(*str == '\0' && *pattern == '\0') return true; if(*str != '\0' && *pattern == '\0') return false; if(*(pattern+1) == '*'){ //a a* || a .* if(*str == *pattern || (*pattern == '.' && *str != '\0')){ return match(str+1, pattern) || match(str, pattern+2) || match(str+1, pattern+2); } //a b* else{ return match(str, pattern+2); } } else{ //a a || a . if(*str == *pattern || (*pattern == '.' && *str != '\0')){ return match(str+1, pattern+1); } //a b else{ return false; } } } };
Java
public class Solution { public boolean match(char[] str, char[] pattern) { if(str == null || pattern == null) return false; return matchHelper(str, pattern, 0, 0); } public static boolean matchHelper(char[] str, char[] pattern, int i, int j) { if(i == str.length && j == pattern.length) return true; if(i != str.length && j == pattern.length) return false; if(j+1 < pattern.length && pattern[j+1] == '*') { if((i != str.length && pattern[j] == str[i]) || (pattern[j] == '.' && i != str.length)) { return matchHelper(str, pattern, i+1, j) || matchHelper(str, pattern, i, j+2) || matchHelper(str, pattern, i+1, j+2); }else { return matchHelper(str, pattern, i, j+2); } }else { if((i != str.length && pattern[j] == str[i]) || (pattern[j] == '.' && i != str.length)) { return matchHelper(str, pattern, i+1, j+1); }else { return false; } } } }