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
首先这道题想到的是回朔法。直接上Code_Ganker大神的回朔代码供大家参考
public static boolean isMatch(String s, String p) {
return helper(s, p, 0, 0);
}
public static boolean helper(String s, String p, int i, int j) {
if (j == p.length())
return i == s.length();
if (j == p.length() - 1 || p.charAt(j + 1) != '*') {
if (i == s.length() || s.charAt(i) != p.charAt(j)
&& p.charAt(j) != '.')
return false;
else
return helper(s, p, i + 1, j + 1);
}
// p.charAt(j+1)=='*'
while (i < s.length()
&& (p.charAt(j) == '.' || s.charAt(i) == p.charAt(j))) {
if (helper(s, p, i, j + 2))
return true;
i++;
}
return helper(s, p, i, j + 2);
}
接下来是自己研究了2天还是没有研究透的动态规划的算法
public static boolean isMatch(String s, String p) {
int row = p.length() + 1;
int col = s.length() + 1;
boolean[][] result = new boolean[row][col];
// 动态规划初始化状态
result[0][0] = true;
for (int i = 1; i < row; i++) {
if (p.charAt(i - 1) == '*')
result[i][0] = result[i - 2][0];
else
result[i][0] = false;
}
// 动态规划状态转移方程
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
// 到达i这个字符之前的字符是*的情况
if (p.charAt(i - 1) == '*') {
if (match(s.charAt(j - 1), p.charAt(i - 2)))
result[i][j] = result[i - 2][j] || result[i][j - 1];
else
result[i][j] = result[i - 2][j];
}
// 到达i这个字符之前的字符不是*的情况
else {
if (match(s.charAt(j - 1), p.charAt(i - 1)))
result[i][j] = result[i - 1][j - 1];
else
result[i][j] = false;
}
}
}
return result[row - 1][col - 1];
}
对于这道题,我没有任何力气去评价它了,尤其是对于“*”这个东西,如果可以骂人的话,我想说XXX。
真的是一道十分恶心的题。