zoukankan      html  css  js  c++  java
  • LeetCode(44): 通配符匹配

    Hard!

    题目描述:

    给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

    '?' 可以匹配任何单个字符。
    '*' 可以匹配任意字符串(包括空字符串)。
    

    两个字符串完全匹配才算匹配成功。

    说明:

    • s 可能为空,且只包含从 a-z 的小写字母。
    • p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *

    示例 1:

    输入:
    s = "aa"
    p = "a"
    输出: false
    解释: "a" 无法匹配 "aa" 整个字符串。

    示例 2:

    输入:
    s = "aa"
    p = "*"
    输出: true
    解释: '*' 可以匹配任意字符串。
    

    示例 3:

    输入:
    s = "cb"
    p = "?a"
    输出: false
    解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
    

    示例 4:

    输入:
    s = "adceb"
    p = "*a*b"
    输出: true
    解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
    

    示例 5:

    输入:
    s = "acdcb"
    p = "a*c?b"
    输入: false

    解题思路:

    这道题通配符匹配问题还是小有难度的,这道里用了贪婪算法Greedy Alogrithm来解,由于有特殊字符*和?,其中?能代替任何字符,*能代替任何字符串,那么我们需要定义几个额外的指针,其中scur和pcur分别指向当前遍历到的字符,再定义pstar指向p中最后一个*的位置,sstar指向此时对应的s的位置,具体算法如下:

    - 定义scur, pcur, sstar, pstar

    - 如果*scur存在

      - 如果*scur等于*pcur或者*pcur为 '?',则scur和pcur都自增1

      - 如果*pcur为'*',则pstar指向pcur位置,pcur自增1,且sstar指向scur

      - 如果pstar存在,则pcur指向pstar的下一个位置,scur指向sstar自增1后的位置

    - 如果pcur为'*',则pcur自增1

    - 若*pcur存在,返回False,若不存在,返回True

    C语言解法一:

     1 bool isMatch(char *s, char *p) {
     2     char *scur = s, *pcur = p, *sstar = NULL, *pstar = NULL;
     3     while (*scur) {
     4         if (*scur == *pcur || *pcur == '?') {
     5             ++scur;
     6             ++pcur;
     7         } else if (*pcur == '*') {
     8             pstar = pcur++;
     9             sstar = scur;
    10         } else if (pstar) {
    11             pcur = pstar + 1;
    12             scur = ++sstar;
    13         } else return false;
    14     } 
    15     while (*pcur == '*') ++pcur;
    16     return !*pcur;
    17 }

    这道题也能用动态规划Dynamic Programming来解,写法跟之前那道题Regular Expression Matching很像,但是还是不一样。外卡匹配和正则匹配最大的区别就是在星号的使用规则上,对于正则匹配来说,星号不能单独存在,前面必须要有一个字符,而星号存在的意义就是表明前面这个字符的个数可以是任意个,包括0个,那么就是说即使前面这个字符并没有在s中出现过也无所谓,只要后面的能匹配上就可以了。而外卡匹配就不是这样的,外卡匹配中的星号跟前面的字符没有半毛钱关系,如果前面的字符没有匹配上,那么直接返回false了,根本不用管星号。而星号存在的作用是可以表示任意的字符串,当然只是当匹配字符串缺少一些字符的时候起作用,当匹配字符串包含目标字符串没有的字符时,将无法成功匹配。

    C++解法一:

     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                 } else {
    15                     dp[i][j] = (s[i - 1] == p[j - 1] || p[j - 1] == '?') && dp[i - 1][j - 1];
    16                 }
    17             }
    18         }
    19         return dp[m][n];
    20     }
    21 };
  • 相关阅读:
    异常处理、网络编程
    内置函数、反射、__str__、__del__、元类
    tomcat 拒绝服务
    html标签
    google 与服务器搭建
    liunx centox ssh 配置
    java 泛型
    Windows Mysql安装
    java 空对象
    java 动态代理(类型信息)
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9139523.html
Copyright © 2011-2022 走看看