算法练习5
Regular Expression Matching
Implement regular expression matching with support for '.' and '*'.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| '.' 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
|
解题思路
题目大意:实现正则式中的'.'和'*' 匹配。
该问题可以具有最优子结构,所以可以用动态规划来求解。
首先分析这个问题,我们把这个问题可以看成是重复的比较字符串s的某个字符和字符串p的某个字符。在这个比较过程中有三种情况:
1 2 3 4 5
| 1, p.charAt(j) == s.charAt(i) 2, p.charAt(j) == '.' 3, p.charAt(j) == '*' 3.1, p.charAt(j-1) != s.charAt(i) 3.2, p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.'
|
基于以上情况,定义dp[i][j]为s串前i个字符与p串前j个字符的匹配状态。那么我们可以得到每种情况对应的状态转移方程:
1 2 3 4 5 6
| 1, if p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1]; 2, if p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1]; 3, if p.charAt(j) == '*' : if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2]; if p.charAt(i-1) == s.charAt(i) || p.charAt(i-1) == '.' : dp[i][j] = dp[i-1][j] || dp[i][j] = dp[i][j-1] || dp[i][j] = dp[i][j-2];
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Solution { public boolean isMatch(String s, String p) { if (s == null || p == null) return false; boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; dp[0][0] = true; for (int i = 0; i < p.length(); i++) { if (p.charAt(i) == '*' && dp[0][i - 1]) { dp[0][i + 1] = true; } } for (int i = 0; i < s.length(); i++) { for (int j = 0; j < p.length(); j++) { if (p.charAt(j) == s.charAt(i)) { dp[i+1][j+1] = dp[i][j]; } if (p.charAt(j) == '.') { dp[i+1][j+1] = dp[i][j]; } if (p.charAt(j) == '*') { if (p.charAt(j -1) != s.charAt(i) && p.charAt(j - 1) != '.') { dp[i + 1][j + 1] = dp[i + 1][j - 1]; } else { dp[i+1][j+1] = (dp[i+1][j] || dp[i][j+1] || dp[i+1][j-1]); } } } }
return dp[s.length()][p.length()]; } }
|