zoukankan      html  css  js  c++  java
  • 力扣算法题—044通配字符匹配

    //此为博客讲解
    //p串中星号的位置很重要,用jStar来表示,还有星号匹配到s串中的位置,
    //使用iStart来表示,这里 iStar 和 jStar 均初始化为 - 1,表示默认情况下是没有星号的。
    //然后再用两个变量i和j分别指向当前s串和p串中遍历到的位置。
    //
    //开始进行匹配,若i小于s串的长度,进行while循环。若当前两个字符相等,
    //或着p中的字符是问号,则i和j分别加1。若p[j] 是星号,那么我们要记录星号的位置,
    //pStar赋为j,此时j再自增1,iStar赋为i。若当前p[j] 不是星号,并且不能跟p[i] 匹配上,
    //那么此时就要靠星号了,若之前星号没出现过,那么就直接跪,比如 s = "aa" 和 p = "c*",
    //此时 s[0] 和 p[0] 无法匹配,虽然p[1] 是星号,但还是跪。如果星号之前出现过,可以强行续一波命,
    //比如 s = "aa" 和 p = "*c",当发现 s[1] 和 p[1] 无法匹配时,但是好在之前 p[0] 出现了星号,
    //我们把 s[1] 交给 p[0] 的星号去匹配。至于如何知道之前有没有星号,这时就能看出 iStar 的作用了,
    //因为其初始化为 - 1,而遇到星号时,其就会被更新为i,那么我们只要检测 iStar 的值,
    //就能知道是否可以使用星号续命。虽然成功续了命,匹配完了s中的所有字符,但是之后我们还要检查p串,
    //此时没匹配完的p串里只能剩星号,不能有其他的字符,将连续的星号过滤掉,如果j不等于p的长度,
    //则返回false,参见代码如下:

     1 class Solution {
     2 public:
     3     bool isMatch(string s, string p) {
     4         int i = 0, j = 0, iStar = -1, jStar = -1;
     5         while (i < s.size()) {
     6             if (s[i] == p[j] || p[j] == '?') {
     7                 ++i; ++j;
     8             }
     9             else if (p[j] == '*') {
    10                 iStar = i;
    11                 jStar = j++;
    12             }
    13             else if (iStar >= 0) {
    14                 i = ++iStar;
    15                 j = jStar + 1;
    16             }
    17             else return false;
    18         }
    19         while (p[j] == '*') ++j;
    20         return j == p.size();
    21     }
    22 };

    //使用动态规划

     1 class Solution {
     2 public:
     3     bool isMatch(string s, string p) {
     4         int m = s.size(), n = p.size();
     5         vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
     6         dp[0][0] = true;
     7         for (int i = 1; i <= n; ++i) {
     8             if (p[i - 1] == '*') dp[0][i] = dp[0][i - 1];
     9         }
    10         for (int i = 1; i <= m; ++i) {
    11             for (int j = 1; j <= n; ++j) {
    12                 if (p[j - 1] == '*') {
    13                     dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
    14                 }
    15                 else {
    16                     dp[i][j] = (s[i - 1] == p[j - 1] || p[j - 1] == '?') && dp[i - 1][j - 1];
    17                 }
    18             }
    19         }
    20         return dp[m][n];
    21     }
    22 };

    //使用递归思想
    //有三种不同的状态,返回0表示匹配到了s串的末尾,但是未匹配成功;
    //返回1表示未匹配到s串的末尾就失败了;返回2表示成功匹配。
    //那么只有返回值大于1,才表示成功匹配。至于为何失败的情况要分类,
    //就是为了进行剪枝。在递归函数中,若s串和p串都匹配完成了,返回状态2。
    //若s串匹配完成了,但p串但当前字符不是星号,返回状态0。若s串未匹配完,
    //p串匹配完了,返回状态1。若s串和p串均为匹配完,且当前字符成功匹配的话,
    //对下一个位置调用递归。否则若p串当前字符是星号,那么我们首先跳过连续的星号
    //。然后我们分别让星号匹配空串,一个字符,两个字符,....,直到匹配完整个s串
    //,对每种情况分别调用递归函数,接下来就是最大的亮点了,也是最有用的剪枝,
    //当前返回值为状态0或者2的时候,返回,否则继续遍历。如果我们仅仅是状态2的时候才返回,
    //因为当返回值为状态0的时候,已经没有继续循环下去的必要了,非常重要的一刀剪枝,参见代码如下:

     1 class Solution {
     2 public:
     3     bool isMatch(string s, string p) {
     4         return helper(s, p, 0, 0) > 1;
     5     }
     6     int helper(string& s, string& p, int i, int j) {
     7         if (i == s.size() && j == p.size()) return 2;
     8         if (i == s.size() && p[j] != '*') return 0;
     9         if (j == p.size()) return 1;
    10         if (s[i] == p[j] || p[j] == '?') {
    11             return helper(s, p, i + 1, j + 1);
    12         }
    13         if (p[j] == '*') {
    14             if (j + 1 < p.size() && p[j + 1] == '*') {
    15                 return helper(s, p, i, j + 1);
    16             }
    17             for (int k = 0; k <= (int)s.size() - i; ++k) {
    18                 int res = helper(s, p, i + k, j + 1);
    19                 if (res == 0 || res == 2) return res;
    20             }
    21         }
    22         return 1;
    23     }
    24 };
  • 相关阅读:
    CentOS中基于不同版本安装重复包的解决方案
    诺讯科技
    SQLMap使用
    python初码
    优秀软件project师必备的7大特性
    3.2 Piecewise Linear Interpolation(站点)
    C#开发Unity游戏教程之游戏对象的属性变量
    java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4
    一键解决ScrollView嵌套ListView仅仅显示一行的问题
    W5500中断寄存器的理解
  • 原文地址:https://www.cnblogs.com/zzw1024/p/10584500.html
Copyright © 2011-2022 走看看