虫虫首页|资源下载|资源专辑|精品软件
登录|注册

您现在的位置是:首页 > 技术阅读 >  每日一题:通配符匹配

每日一题:通配符匹配

时间:2024-02-14

题目44:通配符匹配

给定一个字符串 (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

分析

最近在做回溯题,所以这题使用回溯方法来做,但使用回溯方法很容易超时,所以需要做一些遇到多个连续星号最好提前过滤掉,同时要使用记忆的回溯方法,使用空间换时间,避免不必要的递归,这里移动s和p串的下标来做递归,要用map存储s和p的下标对应的结果,需要将两个下标包装成一个wrapper,同时这个wrapper的结构体要重载运算符,具体见代码:

代码

class Solution {public:    bool isMatch(string &s, string &p) {        return BackTrace(s, p, 0, 0);    }
struct Wrapper { int s_idx; int p_idx; Wrapper(int s, int p) : s_idx(s), p_idx(p) {}
bool operator=(const Wrapper &o) const { return s_idx == o.s_idx && p_idx == o.p_idx; }
bool operator<(const Wrapper &o) const { return s_idx < o.s_idx || (s_idx == o.s_idx && p_idx < o.p_idx); } }; map<Wrapper, bool> used;
bool BackTrace(string &s, string &p, int s_idx, int p_idx) { if (used.find(Wrapper(s_idx, p_idx)) != used.end()) { return used[Wrapper(s_idx, p_idx)]; } int p_size = p.size(); int s_size = s.size(); if (p_idx == p_size) { return s_idx == s_size; } if (s_idx == s_size) { for (int i = p_idx; i < p_size; ++i) { if (p[i] != '*') { return false; } } return true; } if (s[s_idx] == p[p_idx] || p[p_idx] == '?') { bool ret = BackTrace(s, p, s_idx + 1, p_idx + 1); used[Wrapper(s_idx+1, p_idx+1)] = ret; return ret; } if (p[p_idx] == '*') { int no_star_idx = p_idx + 1; for (int i = no_star_idx; i < p_size; ++i) { if (p[i] != '*') { no_star_idx = i; break; } if (i == p_size) { return true; } } bool ret = BackTrace(s, p, s_idx, no_star_idx); used[Wrapper(s_idx, no_star_idx)] = ret; if (ret) return true; ret = BackTrace(s, p, s_idx + 1, no_star_idx - 1); used[Wrapper(s_idx+1, no_star_idx-1)] = ret; return ret; } return false; }};
更多精彩推荐,请关注我们


代码精进之路


  代码精进之路,我们一起成长!



想看懂stl代码,先搞定type_traits是关键

C++线程池的实现

源码分析shared_ptr实现

每日一题:不同路径问题

C++定时器的实现

new[]和delete[]为何要配对使用?