LeetCode——010 Regular Expression Matching


title: LeetCode——010 Regular Expression Matching
author: zzw
top: false
toc: true
mathjax: false
email: [email protected]
date: 2020-02-19 22:05:32
updated: 2020-02-19 22:05:32
img:
summary:
categories: LeetCode
tags: 字符匹配
---

Description

Given an input string (s) and a pattern (p), 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).

Note:
s could be empty and contains only lowercase letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like . or *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:

Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4:

Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".

Example 5:

Input:
s = "mississippi"
p = "mis*is*p*."
Output: false

Solution
one:

  • If the length p is 1, return true if the length is s is 1, and p is the same or '.', Otherwise returns false.
  • If p is the second character is not * s at this time is empty if it returns false, otherwise determine whether the first character to match,
    and the second character from the beginning of each recursive function calls match.
  • If the second character of p *, the following cycle, with the proviso that when s is not empty and the first character match (including p [0] point),
    the function is called to remove the p and s match the first two characters (such the reason is to assume the role at this time is to get in front of an asterisk
    characters appear 0, verify that the match), if the matching returns true, otherwise s remove the first letter (because the first letter of the match,
    we can get rid of s. initials, and p due asterisk can have any number of initials, so do not get rid of),
    to continue the cycle.
  • Recursive function calls return match s and p remove the results of the first two characters (the reason for this is that the processing content asterisk can not match,
    after such s = "ab", p = "ab", directly into the while loop, we found "ab" and "b" do not match, so s to become "b", then the case out of the loop, to return to compare to the last "b" and "b", and return true. As another example, for example, s = "", p = " a", due to the s is empty, do not enter any if and while, only to return to compare the final, returns true, correct).
class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.empty())return s.empty();
        if (p.size() > 1 && p[1] == '*')//记住,‘*’打头没有任何用处
        {
            bool f1 = isMatch(s, p.substr(2));//即,将‘*’视为不起任何作用,直接匹配后面的字符
            bool f2 = (!s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p));//第一个匹配上了,之所以不去除p的第一个字母,是因为‘*’可以当作0个第一个字母匹配
            return f1 || f2;
            //return isMatch(s, p.substr(2)) || (!s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p));
        }
        else//第二个字母不为‘*’,那么就一个个按要求匹配
            return !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1));        
    }
};

Method two: DP Solution:
We can also use the solution to DP, DP define a two-dimensional array, where dp [i] [j] represents the s [0, i), and p [0, j) if the match, then there is the following three conditions:

  1. dp [i] [j] = dp [i - 1] [j - 1];! if p [j - 1] = '*' && (s [i - 1] == p [j - 1] || p [j - 1] ==) '.'; i.e., not for the letter '*', and the characters match, and it determines whether the previous character matches the
  2. dp [i] [j] = dp [i] [j - 2]; if p [j - 1] == '*' and the pattern repeats for 0 times; i.e., in front of the '*' sign obsolete, because ' * 'matches the previous character
  3. dp [i] [j] = dp [i - 1] [j] && (s [i - 1] == p [j - 2] || p [j - 2] == '.'); if p [j - 1]. == ' *' and the pattern repeats for at least 1 times
    i.e., '*' in front of the upper case alphabet letters matched, then it will '*' in front of at least one copy of the letter
class Solution2 {
public:
    bool isMatch(string s, string p) {
        if (p.empty())return s.empty();
        int m = s.size(), n = p.size();
        vector<vector<bool>>dp(m + 1, vector<bool>(n + 1, false));
        dp[0][0] = true;//都为空时
        for (int i = 0; i < m + 1; ++i)
        {
            for (int j = 1; j < n + 1; ++j)
            {
                if (p[j - 1] != '*')
                    dp[i][j] = dp[i][j - 2] || (i && dp[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'));
                else
                    dp[i][j] = i && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
            }
        }
        return dp[m][n];
    }
};

Guess you like

Origin www.cnblogs.com/zzw1024/p/12334081.html