192. 通配符匹配

中文
English

判断两个可能包含通配符“?”和“*”的字符串是否匹配。匹配规则如下:

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

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

样例

样例1

输入:
"aa"
"a"
输出: false

输出2

输入:
"aa"
"aa"
输出: true

输出3

输入:
"aaa"
"aa"
输出: false

输出4

输入:
"aa"
"*"
输出: true
说明: '*' 可以替换任何字符串

输出5

输入:
"aa"
"a*"
输出: true

样例6

输入:
"ab"
"?*"
输出: true
说明: '?' -> 'a' '*' -> 'b'

样例7

输入:
"aab"
"c*a*b"
输出: false
class Solution:
"""
@param s: A string
@param p: A string includes "?" and "*"
@return: is Match?
"""
def isMatch(self, s, p):
# write your code here
self.cache = {}
return self.helper(s, p, s_at=len(s)-1, p_at=len(p)-1) def helper(self, s, p, s_at, p_at):
if (s_at, p_at) in self.cache:
return self.cache[(s_at, p_at)] if p_at < 0:
return s_at < 0 if s_at < 0:
for i in range(0, p_at+1):
if p[i] != "*":
return False
return True if p[p_at] == '?':
is_match = self.helper(s, p, s_at-1, p_at-1)
elif p[p_at] == '*':
is_match = self.helper(s, p, s_at-1, p_at) or \
self.helper(s, p, s_at, p_at-1)
else:
is_match = s_at >= 0 and s[s_at]==p[p_at] and \
self.helper(s, p, s_at-1, p_at-1)
self.cache[(s_at, p_at)] = is_match
return is_match

注意 如果不用cache的话会超时。

更复杂一点的题目:

154. 正则表达式匹配

中文
English

实现支持'.''*'的正则表达式匹配。

'.'匹配任意一个字母。

'*'匹配零个或者多个前面的元素。

匹配应该覆盖整个输入字符串,而不仅仅是一部分。

需要实现的函数是:bool isMatch(string s, string p)

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

样例

样例 1:

输入:"aa","a"
输出:false
解释:
无法匹配

样例 2:

输入:"aa","a*"
输出:true
解释:
'*' 可以重复 a
class Solution:
"""
@param s: A string
@param p: A string includes "." and "*"
@return: A boolean
"""
def isMatch(self, s, p):
# write your code here
self.cache = {}
return self.helper(s, p, s_at=len(s)-1, p_at=len(p)-1) def helper(self, s, p, s_at, p_at):
if (s_at, p_at) in self.cache:
return self.cache[(s_at, p_at)] if p_at < 0:
return s_at < 0
else:
if s_at < 0:
for i in range(p_at, -1, -2):
if p[i] != '*':
return False
return True if p[p_at] == '.':
is_match = self.helper(s, p, s_at-1, p_at-1)
elif p[p_at] == '*':
matched_once = (p_at > 0 and (p[p_at-1] == '.' or p[p_at-1] == s[s_at])) and \
self.helper(s, p, s_at-1, p_at)
matched_none = self.helper(s, p, s_at, p_at-2)
is_match = matched_once or matched_none
else:
is_match = s_at >= 0 and s[s_at]==p[p_at] and \
self.helper(s, p, s_at-1, p_at-1)
self.cache[(s_at, p_at)] = is_match
return is_match

算法思路整体上和上面题目一样,唯一的区别就是pattern -2,还有对于空串的匹配截止条件。

"" 匹配类似"a*b*c*"这样的模式。

当然,从前往后的匹配解法也是可以的,也就是匹配的时候pattern往前多看一步看是不是*来决定走一步还是走两步,参考代码:

class Solution:
"""
@param s: A string
@param p: A string includes "?" and "*"
@return: is Match?
"""
def isMatch(self, source, pattern):
return self.is_match_helper(source, 0, pattern, 0, {}) # source 从 i 开始的后缀能否匹配上 pattern 从 j 开始的后缀
# 能 return True
def is_match_helper(self, source, i, pattern, j, memo):
if (i, j) in memo:
return memo[(i, j)] # source is empty
if len(source) == i:
return self.is_empty(pattern[j:]) if len(pattern) == j:
return False if j + 1 < len(pattern) and pattern[j + 1] == '*':
matched = self.is_match_char(source[i], pattern[j]) and self.is_match_helper(source, i + 1, pattern, j, memo) or \
self.is_match_helper(source, i, pattern, j + 2, memo)
else:
matched = self.is_match_char(source[i], pattern[j]) and \
self.is_match_helper(source, i + 1, pattern, j + 1, memo) memo[(i, j)] = matched
return matched def is_match_char(self, s, p):
return s == p or p == '.' def is_empty(self, pattern):
if len(pattern) % 2 == 1:
return False for i in range(len(pattern) // 2):
if pattern[i * 2 + 1] != '*':
return False
return True

829. 字模式 II

中文
English

给定一个pattern和一个字符串str,查找str是否遵循相同的模式。
这里遵循的意思是一个完整的匹配,在一个字母的模式和一个非空的单词str之间有一个双向连接的模式对应。(如果a对应s,那么b不对应s。例如,给定的模式= "ab", str = "ss",返回false)。

样例

样例1

输入:
pattern = "abab"
str = "redblueredblue"
输出: true
说明: "a"->"red","b"->"blue"

样例2

输入:
pattern = "aaaa"
str = "asdasdasdasd"
输出: true
说明: "a"->"asd"

样例3

输入:
pattern = "aabb"
str = "xyzabcxzyabc"
输出: false

注意事项

您可以假设模式str只包含小写字母

class Solution:
"""
@param pattern: a string,denote pattern string
@param str: a string, denote matching string
@return: a boolean
"""
def wordPatternMatch(self, pattern, str):
# write your code here
self.word_dict = {}
self.word_match = {}
return self.dfs(pattern, str) def dfs(self, pattern, s):
if not pattern:
return not s if not s:
return not pattern pattern_char = pattern[0]
if pattern_char in self.word_dict:
word_to_match = self.word_dict[pattern_char]
return s[:len(word_to_match)] == word_to_match and \
self.dfs(pattern[1:], s[len(word_to_match):])
else:
for i in range(0, len(s)):
word = s[:i+1]
if word in self.word_match:
continue
self.word_dict[pattern_char] = word
self.word_match[word] = pattern_char
if self.dfs(pattern[1:], s[i+1:]):
return True
del self.word_dict[pattern_char]
del self.word_match[word]
return False """
这里我们为什么需要一个额外的 Set<String> 呢? 一个好的测试用例是:
pattern: "bdpbibletwuwbvh"
str: "aaaaaaaaaaaaaaa" 这里第一次执行时, map中匹配了 b -> a
递归进去以后第二次执行时,d 没有在 map 中,所以跳过了map的匹配检测,
所以进入循环体, 这时第二个word 又是 a, 按道理 a 应该被 b 匹配并且之前应该在map.containsKey的检查中跳出, 但现在并没有跳出,而是试图绑匹配给另一个pattern的字母 d,
很明显 b != d 重复绑定不是正确结果, 所以需要continue掉这次尝试。
"""

dfs 正则表达式的更多相关文章

  1. Linux正则表达式grep与egrep

    grep -io "http:/=[A-Z0-9]\{16\}" ./wsxf.txt >wsxf_urls.txt Linux正则表达式grep与egrep 正则表达式:它 ...

  2. grep与正则表达式,grep、egrep和fgrep

    grep用法详解:grep与正则表达式 首先要记住的是: 正则表达式与通配符不一样,它们表示的含义并不相同!正则表达式只是一种表示法,只要工具支持这种表示法, 那么该工具就可以处理正则表达式的字符串. ...

  3. 第八届 蓝桥杯 7、正则问题 dfs

    描述:正则问题 考虑一种简单的正则表达式:只由 x ( ) | 组成的正则表达式.小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串 ...

  4. 蓝桥杯-正则问题(dfs,解决()的计算)

    历届试题 正则问题   时间限制:1.0s   内存限制:256.0MB      问题描述 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长 ...

  5. 蓝桥杯 正则问题(dfs)

    1607: 正则问题 时间限制: 1 Sec  内存限制: 256 MB提交: 34  解决: 13[提交][状态][讨论版] 题目描述 考虑一种简单的正则表达式:只由 x ( ) | 组成的正则表达 ...

  6. grep用法详解:grep与正则表达式【转】

    转自:http://blog.csdn.net/hellochenlian/article/details/34088179 grep用法详解:grep与正则表达式 首先要记住的是: 正则表达式与通配 ...

  7. DFS 算法模板

    dfs算法模板: 1.下一层是多节点的dfs遍历 def dfs(array or root, cur_layer, path, result): if cur_layer == len(array) ...

  8. 2019-01-31 Python学习之BFS与DFS实现爬取邮箱

    今天学习了python网络爬虫的简单知识 首先是一个爬取百度的按行读取和一次性爬取 逐行爬取 for line in urllib.request.urlopen("http://www.b ...

  9. JS正则表达式常用总结

    正则表达式的创建 JS正则表达式的创建有两种方式: new RegExp() 和 直接字面量. //使用RegExp对象创建 var regObj = new RegExp("(^\\s+) ...

随机推荐

  1. Go:为何带来泛型

    中文版 English version 介绍 [这是在Gophercon 2019上发表的演讲版本.视频链接可供使用.] 这篇文章是关于向Go添加泛型的意义,以及为什么我认为我们应该这样做.我还将介绍 ...

  2. 【Gamma】项目展示

    团队成员介绍 大娃 :后端开发人员,主要工作为后端开发,文档撰写. 大娃的个人博客 二娃 PM,主要工作为项目进度把控,例会博客撰写. 二娃的个人博客 三娃* PM,主要工作为项目进度把控,用户需求分 ...

  3. JNA 调用操作系统函数 和 系统调用

    linux系统调用syscall 表:https://filippo.io/linux-syscall-table/ Linux Namespace 特性简要介绍 原文:https://iliangq ...

  4. C#开源录音组件、录像组件、录屏组件及demo源码

    在多媒体系统中,一般都会涉及到录音.录像.录屏问题,采集得到的数据可以用来传输.播放.或存储.所以,对于像课件录制系统.语音视频录制系统.录屏系统等,多媒体数据的采集就是最基础的功能之一. MCapt ...

  5. 测试效率加倍提升!shell 高阶命令快来 get 下!

    背景 目前大部分的项目都是部署在Linux系统上,作为测试,掌握常用Linux命令是必须的技能.很多的工作了好几年的测试人员可能还只会简单的ls.cd.cat等等这些命令,这些命令是可以应付工作的大部 ...

  6. CentOS7 下 yum 安装 Docker CE

    前言 Docker 使用越来越多,安装也很简单,本次记录一下基本的步骤. Docker 目前支持 CentOS 7 及以后的版本,内核要求至少为 3.10. Docker 官网有安装步骤,本文只是记录 ...

  7. Sitecore 9 您应该了解的所有新功能和变化

    信不信由你,当我谈论Sitecore时,我感到非常兴奋.这是一个充满潜力和机遇的伟大平台 如果你能想象一个刚刚进行过一次双重训练的人,一个特大号的星巴克,并且刚刚在创纪录的时间内完成了中国忍者勇士的障 ...

  8. 记lombok@Data和@Builder一起用无法添加无参构造方法的坑

    转自:https://blog.csdn.net/w605283073/article/details/89221853 今天和小伙伴讨论一个mybatis-plus的一个诡异问题,最后定位到原因竟然 ...

  9. LocalDateTime代替Date

    为什么需要LocalDate.LocalTime.LocalDateTime Date如果不格式化,打印出的日期可读性差 Tue Sep 10 09:34:04 CST 2019 使用SimpleDa ...

  10. CRLF will be replaced by LF in XXX when git commit

    转载自Git-warning: CRLF will be replaced by LF in XXX 今天,普通平凡的一天,平凡的使用 git add .,然后又出现一个之前没遇到的错误提示 . 真开 ...