[LeetCode] Wildcard Matching 外卡匹配

简介:

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*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 解法一:

bool isMatch(char *s, char *p) {
    char *scur = s, *pcur = p, *sstar = NULL, *pstar = NULL;
    while (*scur) {
        if (*scur == *pcur || *pcur == '?') {
            ++scur;
            ++pcur;
        } else if (*pcur == '*') {
            pstar = pcur++;
            sstar = scur;
        } else if (pstar) {
            pcur = pstar + 1;
            scur = ++sstar;
        } else return false;
    } 
    while (*pcur == '*') ++pcur;
    return !*pcur;
}

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

C++ 解法二:

class Solution {
public:
    bool isMatch(string s, string p) {
        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 = 1; i <= n; ++i) {
            if (p[i - 1] == '*') dp[0][i] = dp[0][i - 1];
        }
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p[j - 1] == '*') {
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                } else {
                    dp[i][j] = (s[i - 1] == p[j - 1] || p[j - 1] == '?') && dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};

本文转自博客园Grandyang的博客,原文链接:外卡匹配[LeetCode] Wildcard Matching ,如需转载请自行联系原博主。

相关文章
|
算法
LeetCode 43字符串相乘&44通配符匹配
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
112 0
LeetCode 43字符串相乘&44通配符匹配
LeetCode精讲题 10正则表达式匹配(动态规划)
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和'*'的正则表达式匹配。 '.'匹配任意单个字符 '*'匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
138 0
LeetCode精讲题 10正则表达式匹配(动态规划)
|
索引 Python
LeetCode 44. Wildcard Matching
给定输入字符串s和模式串(p),实现通配符模式匹配支持'?' 和'*'.
84 0
LeetCode 524. 通过删除字母匹配到字典里最长单词
LeetCode 524. 通过删除字母匹配到字典里最长单词
74 0
LeetCode每日一题——792. 匹配子序列的单词数
给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。
107 0
|
iOS开发
LeetCode每日一题——1773. 统计匹配检索规则的物品数量
给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。
84 0
|
算法 Java C++
LeetCode(算法)- 10. 正则表达式匹配
LeetCode(算法)- 10. 正则表达式匹配
97 0
LeetCode(算法)- 10. 正则表达式匹配
|
Java C++
LeetCode(剑指 Offer)- 19. 正则表达式匹配
LeetCode(剑指 Offer)- 19. 正则表达式匹配
104 0
LeetCode(剑指 Offer)- 19. 正则表达式匹配
|
算法 前端开发 程序员
「LeetCode」剑指Offer-19正则表达式匹配⚡️
「LeetCode」剑指Offer-19正则表达式匹配⚡️
122 0
「LeetCode」剑指Offer-19正则表达式匹配⚡️
|
存储 算法
☆打卡算法☆LeetCode 44、通配符匹配 算法解析
“给定一个字符串和一个字符模式,实现一个通配符匹配。”