LeetCode 10. Regular Expression Matching(正则表达式匹配)
2018-03-16 19:57
393 查看
题目描述: Implement regular expression matching with support for
'.' 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分析:
题意:给定两个字符串,一般的字符都是一一对应匹配,存在两个特殊字符:①
思路:由于两个特殊字符的存在,那么匹配就出现了多种可能性,如果两个字符串足够长,使用DFS暴力搜索绝对会超时。我们采用动态规划的思想来求出递推公式:假设字符串s和p的长度分别为n1、n2,构造数组dp[n1+1][n2+1],初始化为false(其中dp[0][0] = true)。假设我们当前考察s[0→(i-1)]和p[0→(j-1)]的匹配关系,那么根据p[j-1]的取值分两类讨论。
①p[j-1]不为'*'时,如果s[0→(i-2)]和p[0→(j-2)]匹配,我们只需要s[i-1]和p[j-1]相等或者p[j-1]为'.'即可。
dp[i][j] = (i - 1 >= 0) && dp[i - 1][j - 1] && ((s[i - 1] == p[j - 1]) || (p[j - 1] == '.'))
②p[j-1]为'*'时,又分别为两种情况:
Ⅰ.p[j-1]此时恰好停止匹配前驱字符(即匹配零个),此时我们只需要保证s[0→(i-1)]和p[0→(j-3)]匹配;Ⅱ.p[j-1]还在继续匹配前驱字符,我们必须保证s[0→(i-2)]和p[0→(j-1)]匹配,与此同时,p[j-2]需要和s[i-1]相等或者p[j-2]为'.'即可。
dp[i][j] = (j - 2 >= 0 && dp[i][j - 2]) || (i - 1 >= 0 && j - 2 >= 0 && dp[i - 1][j] && ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')))
代码:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool isMatch(string s, string p) {
int n1 = s.length(), n2 = p.length();
// Exceptional Case:
if(n1 == 0 && n2 == 0){
return true;
}
if(n1 != 0 && n2 == 0){
return false;
}
// create
vector<vector<bool>> dp(n1 + 1, vector<bool>(n2 + 1, false));
// init
dp[0][0] = true;
for(int i = 1; i <= n1; i++){
dp[i][0] = false;
}
// dp
for(int i = 0; i <= n1; i++){
for(int j = 1; j <= n2; j++){
if(p[j - 1] != '*'){
dp[i][j] = (i - 1 >= 0) && dp[i - 1][j - 1] && ((s[i - 1] == p[j - 1]) || (p[j - 1] == '.'));
}
else if(p[j - 1] == '*'){
// attention: ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')) is different from (s[i - 1] == p[j - 2] || p[j - 2] == '.')
dp[i][j] = (j - 2 >= 0 && dp[i][j - 2]) || (i - 1 >= 0 && j - 2 >= 0 && dp[i - 1][j] && ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')));
}
}
}
return dp[n1][n2];
}
};
'.'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分析:
题意:给定两个字符串,一般的字符都是一一对应匹配,存在两个特殊字符:①
'.'可以匹配任意一个字符;②
'*'可以匹配零个或者多个它自身的前驱字符。判断两个字符串是否能完成匹配。
思路:由于两个特殊字符的存在,那么匹配就出现了多种可能性,如果两个字符串足够长,使用DFS暴力搜索绝对会超时。我们采用动态规划的思想来求出递推公式:假设字符串s和p的长度分别为n1、n2,构造数组dp[n1+1][n2+1],初始化为false(其中dp[0][0] = true)。假设我们当前考察s[0→(i-1)]和p[0→(j-1)]的匹配关系,那么根据p[j-1]的取值分两类讨论。
①p[j-1]不为'*'时,如果s[0→(i-2)]和p[0→(j-2)]匹配,我们只需要s[i-1]和p[j-1]相等或者p[j-1]为'.'即可。
dp[i][j] = (i - 1 >= 0) && dp[i - 1][j - 1] && ((s[i - 1] == p[j - 1]) || (p[j - 1] == '.'))
②p[j-1]为'*'时,又分别为两种情况:
Ⅰ.p[j-1]此时恰好停止匹配前驱字符(即匹配零个),此时我们只需要保证s[0→(i-1)]和p[0→(j-3)]匹配;Ⅱ.p[j-1]还在继续匹配前驱字符,我们必须保证s[0→(i-2)]和p[0→(j-1)]匹配,与此同时,p[j-2]需要和s[i-1]相等或者p[j-2]为'.'即可。
dp[i][j] = (j - 2 >= 0 && dp[i][j - 2]) || (i - 1 >= 0 && j - 2 >= 0 && dp[i - 1][j] && ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')))
代码:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool isMatch(string s, string p) {
int n1 = s.length(), n2 = p.length();
// Exceptional Case:
if(n1 == 0 && n2 == 0){
return true;
}
if(n1 != 0 && n2 == 0){
return false;
}
// create
vector<vector<bool>> dp(n1 + 1, vector<bool>(n2 + 1, false));
// init
dp[0][0] = true;
for(int i = 1; i <= n1; i++){
dp[i][0] = false;
}
// dp
for(int i = 0; i <= n1; i++){
for(int j = 1; j <= n2; j++){
if(p[j - 1] != '*'){
dp[i][j] = (i - 1 >= 0) && dp[i - 1][j - 1] && ((s[i - 1] == p[j - 1]) || (p[j - 1] == '.'));
}
else if(p[j - 1] == '*'){
// attention: ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')) is different from (s[i - 1] == p[j - 2] || p[j - 2] == '.')
dp[i][j] = (j - 2 >= 0 && dp[i][j - 2]) || (i - 1 >= 0 && j - 2 >= 0 && dp[i - 1][j] && ((s[i - 1] == p[j - 2]) || (p[j - 2] == '.')));
}
}
}
return dp[n1][n2];
}
};
相关文章推荐
- [LeetCode][Facebook面试题] 通配符匹配和正则表达式匹配,题 Wildcard Matching
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
- LeetCode 10 正则表达式匹配
- leetcode Wildcard Matching ,Regular Expression Matching (正则表达式匹配和通配符匹配)
- LeetCode 10 Regular Expression Matching (正则表达式匹配)
- 判断正则表达式是否匹配 Regular Expression Matching @LeetCode
- leetcode 10.Regular Expression Matching(正则表达式匹配) 解题思路和方法
- [leetcode]Regular Expression Matching(正则表达式的匹配)
- leetcode(10) - Regular Expression Matching 正则表达式匹配
- [LeetCode] Regular Expression Matching 正则表达式匹配
- LeetCode 10. Regular Expression Matching(正则表达式匹配)
- 【LeetCode-面试算法经典-Java实现】【010-Regular Expresssion Matching(正则表达式匹配)】
- Leetcode 10. 正则表达式匹配
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
- LeetCode:10 正则表达式匹配 C++
- LeetCode--Regular Expression Matching 正则表达式匹配
- [LeetCode] 10. Regular Expression Matching 正则表达式匹配
- [Leetcode] Regular expression matching 正则表达式匹配
- 正则表达式匹配-leetcode Regular Expression Matching
- 《剑指offer》-正则表达式匹配