zoukankan      html  css  js  c++  java
  • 【LeetCode】010. Regular Expression Matching

    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

    题解:

      这种题是最无语的。。。我试着用遍历做,当 s 为空,p 不为空时的判定怎么也总结不出规律了。还是得用递归做

      注意  ’*‘ 之前必须有字符供其匹配。s = "a", p = "*",s 和 p 不匹配。

      1. 当 s 和 p 都为空时,判定 s 和 p 匹配成功

      2. 当 p 元素个数大于等于 2 ,且第二个元素是‘*’时,那么有两种可能:

        • ‘*’ 之前的字符匹配 0 次,即跳过这两个字符。
        • s 和 p 首字符匹配 : s[0] == p[0] || p[0] == '.'。注意此时 s 需要遍历下一个字符,而 p 保持遍历元素不变,因为 此元素和 ’*‘ 可用来匹配若干次。    

      3. 当 p 第二个元素不是 ’*‘ 或 p 只有一个元素时,挨个去匹配。

    Solution 1

     1 class Solution {
     2 public:
     3     bool isMatch(string s, string p) {
     4         if (s.empty() && p.empty()) 
     5             return true;
     6         if (p.size() > 1 && p[1] == '*') {
     7             return isMatch(s, p.substr(2)) || (!s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p));
     8         } else {
     9             return !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1));
    10         }
    11     }
    12 };

    Solution 2

      发现凡是字符串数组类的区间问题(匹配,区间最大最小)貌似都可以用 DP 尝试。

     This problem has a typical solution using Dynamic Programming. We define the state P[i][j] to be true if s[0..i) matches p[0..j) and false otherwise. Then the state equations are: 
    a. P[i][j] = P[i - 1][j - 1],                   

      if p[j - 1] != ‘*’ && (s[i - 1] == p[j - 1] || p[j - 1] == ‘.’); 
    b. P[i][j] = P[i][j - 2],                   

      if p[j - 1] == ‘*’ and the pattern repeats for 0 times; 
    c. P[i][j] = P[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. 

     1 class Solution {
     2 public:
     3     bool isMatch(string s, string p) {
     4         int m = s.length(), n = p.length(); 
     5         vector<vector<bool> > dp(m + 1, vector<bool> (n + 1, false));
     6         dp[0][0] = true;
     7         for (int i = 0; i <= m; i++)
     8             for (int j = 1; j <= n; j++)
     9                 if (p[j - 1] == '*')
    10                     dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
    11                 else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
    12         return dp[m][n];
    13     }
    14 };
  • 相关阅读:
    编写简单的c运行库(一)
    c中函数参数传递
    MSVC命令行参数
    在C#中对List<>进行排序
    向DataTable中添加一行数据的做法
    获取本机IP(考虑多块网卡、虚拟机等复杂情况)
    [转]在C#中判断一个文本文件的编码方式
    关于C#使用XML序列化的一些注意事项
    C#中的类型和SQL Server中的类型对应关系
    关于DLL文件和EXE文件不在同一目录下的设置
  • 原文地址:https://www.cnblogs.com/Atanisi/p/8645058.html
Copyright © 2011-2022 走看看