原文地址: 正则表达式匹配
实现正则表达式匹配需要支持'.'和'*'.
'.' 匹配任何一个字符.
'*' 匹配0或以上的前一个元素.
匹配应该覆盖整个输入字符串(不是部分)。
函数原型应该是:
bool isMatch(const char *s, const char *p)
一些例子:
isMatch("aa","a") return false
isMatch("aa","aa") return true
isMatch("aaa","aa") return false
isMatch("aa", "a*") return true
isMatch("aa", ".*") return true
isMatch("ab", ".*") return true
isMatch("aab", "c*a*b") return true
- 分析
首先,这是最困难的问题之一。很难去考虑所有不同的情况。这个问题应该简化为处理2个基本情况:- 第二字符匹配是'*'
- 第二字符匹配不是'*'
对于第一种情况, 如果第一个字符的匹配是'.', 第一个字符匹配和字符串应该是相同的,然后继续匹配剩下的部分.
对于第二种情况, 如果第一个字符的匹配不是'.'或者第一个匹配字符是恒等于字符串中的某个字符,然后继续匹配剩下的部分.
Java 解决方案 1 (简单的)
public class Solution {
public boolean isMatch(String s, String p) {
if(p.length() == 0)
return s.length() == 0;
//p's length 1 is special case
if(p.length() == 1 || p.charAt(1) != '*'){
if(s.length() < 1 || (p.charAt(0) != '.' && s.charAt(0) != p.charAt(0)))
return false;
return isMatch(s.substring(1), p.substring(1));
}else{
int len = s.length();
int i = -1;
while(i<len && (i < 0 || p.charAt(0) == '.' || p.charAt(0) == s.charAt(i))){
if(isMatch(s.substring(i+1), p.substring(2)))
return true;
i++;
}
return false;
}
}
}
Java 解决方案 2 (更受欢迎)
public boolean isMatch(String s, String p) {
// base case
if (p.length() == 0) {
return s.length() == 0;
}
// special case
if (p.length() == 1) {
// if the length of s is 0, return false
if (s.length() < 1) {
return false;
}
//if the first does not match, return false
else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
return false;
}
// otherwise, compare the rest of the string of s and p.
else {
return isMatch(s.substring(1), p.substring(1));
}
}
// case 1: when the second char of p is not '*'
if (p.charAt(1) != '*') {
if (s.length() < 1) {
return false;
}
if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
return false;
} else {
return isMatch(s.substring(1), p.substring(1));
}
}
// case 2: when the second char of p is '*', complex case.
else {
//case 2.1: a char & '*' can stand for 0 element
if (isMatch(s, p.substring(2))) {
return true;
}
//case 2.2: a char & '*' can stand for 1 or more preceding element,
//so try every sub string
int i = 0;
while (i<s.length() && (s.charAt(i)==p.charAt(0) || p.charAt(0)=='.')){
if (isMatch(s.substring(i + 1), p.substring(2))) {
return true;
}
i++;
}
return false;
}
}