实现支持“。”的正则表达式匹配 和“ *”。
‘。’ 匹配任何单个字符。
'*'匹配零个或多个前一个元素。
匹配项应覆盖整个输入字符串(而非部分)。
函数原型应该是:
bool isMatch(const char * s,const char * p)
一些示例:
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
1.分析
首先,这是最困难的问题之一。很难考虑所有不同的情况。该问题应简化为处理2种基本情况:
模式的第二个字符为“ *”
模式的第二个字符不是“ *”
对于第一种情况,如果pattern的第一个字符不是“。”,则pattern和string的第一个字符应相同。然后继续匹配其余部分。
对于第二种情况,如果模式的第一个字符为“。” 或pattern的第一个字符==字符串的第一个i字符,继续匹配其余部分。
2. Java解决方案1(简短)
接受以下Java解决方案。
public class Solution {
public boolean isMatch(String s, String p) {
if(p.length() == 0)
return s.length() == 0;
//普的长度1是特殊情况
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;
}
}
}
3. Java解决方案2(更易读)
public boolean isMatch(String s, String p) {
//基本情况
if (p.length() == 0) {
return s.length() == 0;
}
//特例
if (p.length() == 1) {
//如果s的长度为0,则返回false
if (s.length() < 1) {
return false;
}
//如果第一个不匹配,返回false
else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
return false;
}
//否则,比较s和p的其余字符串。
else {
return isMatch(s.substring(1), p.substring(1));
}
}
//情况1:当p的第二个字符不是'*'
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));
}
}
//情况2:当p的第二个字符为'*'时,为复杂情况。
else {
///壳体2.1:一个char& '*'可以代表0元件
if (isMatch(s, p.substring(2))) {
return true;
}
//情况2.2:char&'*'可以代表1个或多个前面的元素,
//因此请尝试每个子字符串
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;
}
}
Java解决方案3-使用索引
我们还可以添加一个辅助方法来使用索引,而不是递归地传递子字符串。
public boolean isMatch(String s, String p) {
return helper(s, p, 0, 0);
}
private boolean helper(String s, String p, int i, int j) {
if (i >= s.length() && j >= p.length()) {
return true;
}
if (j < p.length() - 1 && p.charAt(j + 1) == '*') {
if (helper(s, p, i, j + 2)) {
return true;
}
if (p.charAt(j) == '.') {
for (int k = i; k < s.length(); k++) {
if (helper(s, p, k + 1, j + 2)) {
return true;
}
}
} else {
for (int k = i; k < s.length(); k++) {
if (s.charAt(k) == p.charAt(j)) {
if (helper(s, p, k + 1, j + 2)) {
return true;
}
} else {
break;
}
}
}
} else if (i < s.length() && j < p.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.')) {
return helper(s, p, i + 1, j + 1);
}
return false;
}