zoukankan      html  css  js  c++  java
  • Leetcode: 10. Regular Expression Matching

    Description

    Implement regular expression matching with support for '.' and '*'.

    Example

    '.' 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
    

    思路

    • 匹配问题
    • '.' 匹配任意单个字符,'*' 匹配前面的字符0次或多次
    • 因为需要考虑前面的字符,所以从后往前匹配。
    • 考虑 '*'时的特殊情况,如果 ' * '前面的字符和要匹配的一样,则分两张情况,即匹配0次或多次
    • 如果不一样,则要匹配的不变,然后跳到*字符前面的前面。
    • 没有说清楚,看代码吧

    代码

    class Solution {
    public:
        bool isMatch(string s, string p) {
            int slen = s.size();
            int plen = p.size();
            
            return matchFunc(s, slen - 1, p, plen - 1);
        }
        
        bool matchFunc(string& s, int i, string &p, int j){
            if(i < 0 && j < 0) return true;
            if(i < 0 ) return p[j] == '*' ? matchFunc(s, i, p, j - 2) : false;
            if(j < 0) return false;
            
            if(s[i] == p[j] || p[j] == '.'){
                return matchFunc(s, i - 1, p, j - 1);
            }
            else if(p[j] == '*'){ 
                bool res = false;
                //特殊情况
                if(j - 1 >= 0){
                    if(p[j - 1] == '.' || p[j - 1] == s[i])
                        res =  matchFunc(s, i - 1, p, j) || matchFunc(s, i - 1, p, j - 2);
                }
                
                return res || matchFunc(s, i, p, j - 2);
            }
            
            return false;
        }
    };
    

    动态规划

    • 再讨论区里面还看到了一种动态规划的算法。在这里也作一个介绍,不得不感叹一句,大佬还是多呀。

    • dp[i][j] 表示s[0..i)和p[0..j)的匹配结果,若为ture,则匹配,否则不匹配

    • 则一共有以下状态:

      • dp[i][j] = dp[i - 1][j - 1],if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.'),注意下标的控制,dp[i][j]的下标是长度,而p[j-1]对应于dp[i][j]
      • dp[i][j] = dp[i][j - 2], if p[j - 1] == '*', 且匹配0次
      • dp[i][j] = dp[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'),此时p[j - 1] == '*' 且至少匹配一次
    • 代码如下:

      class Solution {
      public:
          bool isMatch(string s, string p) {
              int slen = s.size();
              int plen = p.size();
          
              vector<vector<bool>> dp(slen + 1, vector<bool>(plen + 1, false));
              dp[0][0] = true;
              for(int i = 0; i <= slen; ++i){
                  for(int j = 1; j <= plen; ++j){
                      if(p[j - 1] == '*'){
                          dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
                      }
                      else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
                  }
              }
              
              return dp[slen][plen];
          }
      };
      

    总结

    • 递归往往可以改善的
    • 向大佬学习!
  • 相关阅读:
    图像,script,link 空地址带来的困惑
    localStorage变更事件当前页响应新解-awen
    opencv在ios上的开发教程
    torch-ios框架XCODE使用备忘
    重拾老本行_图像处理
    dialogic d300语音卡驱动重装后启动报错问题解决方法
    Winpcap构建用户级网桥
    winpcap usb山寨网卡识别
    最近这段时间
    银行IT入门深似海
  • 原文地址:https://www.cnblogs.com/lengender-12/p/6813650.html
Copyright © 2011-2022 走看看