leetcode 10. Regular Expression Matching
只有两种特殊字符*和.
- 动态规划DP
- empty text与empty pattern是match的
- 用状态表T[i + 1][j + 1]来表示text[0...i]与pattern[0...j]的匹配状态
- 当pattern[j]是普通字符或’.’的时候可以归为一种简单的情况
- 这时候如果text[i] == patter[j] 或 pattern[j] == ‘.’,那么text[0...i]与pattern[0...j]的匹配状态取决于text[0...i-1]与pattern[0...j-1]的状态,即T[i + 1][j + 1] = T[i][j]
- 当pattern[j]是字符’*’的时候可以归为另外一种情况
- 这时候text[0...i]与pattern[0...j]的匹配状态可以取决于两种子串的匹配的状态,一种子串是字符pattern[j-1]还没有出现,另一种子串是字符pattern[j-1]还已经出现。第一种子情况T[i + 1][j + 1]直接取决于T[i + 1][j - 1]。另一种子情况text[0...i]与pattern[0...j]是匹配的当且仅当text[0...i-1]与pattern[0...j]是匹配的,而且text[i] == pattern[j] 或者pattern[j] == ‘.’。
- 特殊情况。空串与其他不为空的pattern,只有一种递归关系,T[0][j + 1] = T[0][j - 1]
- 当pattern[j]是普通字符或’.’的时候可以归为一种简单的情况
- 归纳公式
- T[i][j] = T[i - 1][j - 1] if text[i] == pattern[j] || pattern[j] == ‘.’
- T[i][j] = T[i][j - 2] 0 occurrence if pattern[j] == ‘*’
- T[i][j] = T[i - 1][j] if text[i] = pattern[j - 1] || pattern[j - 1] == ‘.’ if pattern[j] == ‘*’
- T[i][j] = false else
- Example
- text: "xaabyc" pattern: "xa*b.c"
-
0
1
2
3
4
5
6
x
a
*
b
.
c
0
T
F
F
F
F
F
F
1
x
F
T
F
T
F
F
F
2
a
F
F
T
T
F
F
F
3
a
F
F
F
T
F
F
F
4
b
F
F
F
F
T
F
F
5
y
F
F
F
F
F
T
F
6
c
F
F
F
F
F
F
T
class Solution { public: bool isMatch(string s, string p) { const int rowNum = int(s.length()) + 1; const int colNum = int(p.length()) + 1; bool table[rowNum][colNum]; table[0][0] = true; for (int i = 1; i < rowNum; i++) { table[i][0] = false; } for (int i = 1; i < colNum; i++) { table[0][i] = p[i - 1] == '*'?table[0][i - 2]:false; } for (int i = 1; i < rowNum; i++) { for (int j = 1; j < colNum; j++) { if (s[i - 1] == p[j - 1] || p[j - 1] == '.') { table[i][j] = table[i - 1][j - 1]; } else if (p[j - 1] == '*') { bool flag1 = table[i][j - 2], flag2 = false; if (s[i - 1] == p[j - 2] || p[j - 2] == '.') { flag2 = table[i - 1][j]; } table[i][j] = flag1 || flag2; } else { table[i][j] = false; } } } for (int i = 0; i < rowNum; i++) { for (int j = 0; j < colNum; j++) { cout << table[i][j] << " "; } cout << endl; } return table[rowNum - 1][colNum - 1]; } };