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. tomcat Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

      1.情景展示 tomcat 日志时不时会报出如下异常信息,到底是怎么回事? java.lang.IllegalArgumentException: Invalid character found ...

  2. Gamma阶段第六次scrum meeting

    每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...

  3. TRex,一个基于DPDK的数据包发生器,测试仪

    1. introduction TRex是cisco基于Intel dpdk开发的软件程序.推荐在CentOS/RHEL 7.6, 64bits中运行,否则connectx-4网卡不可使用. 笔者在U ...

  4. Ansible13:Playbook循环语句

    目录 循环语句 简介 loop关键字说明 在循环语句中注册变量 旧循环语句 1. with_items 2. with_nested 3. with_dict 4. with_fileglob 5. ...

  5. ubuntu18 docker中部署ELK

    ELK是ElasticSearch.Logstash.Kibana的简称,一般用于日志系统,从日志收集,日志转储,日志展示等入手,用以提供简洁高效的日志处理机制. 鉴于没有额外的机器,这里就用dock ...

  6. Java学习:线程池

    线程池 线程池概念:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源. 线程池:容器-->集合(ArrayList,Hash ...

  7. NVDLA软件架构和源码解析 第一章—内核驱动【华为云技术分享】

    驱动整体设计介绍 不同的processor Nvidia DLA的内核驱动KMD(Kernel mode driver)中,并不是把DLA当成一个设备来控制,而是把不同的功能模块当做不同的proces ...

  8. 带着canvas去流浪系列之八 碰撞【华为云技术分享】

    [摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生A ...

  9. 基于Dapper的开源LINQ扩展,且支持分库分表自动生成实体二

    LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼. 文档地址: https://lining ...

  10. 让div在body中任意拖动

    HTML代码 <div id="idOuterDiv" class="CsOuterDiv"> </div> CSS代码 body { ...