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. mysql 基本操作二

    1.查询数据 MariaDB [jason]> offset ; 默认是从偏移量为0 处开始查村数据,通过指定offset 可以从offset 处开始取数 2.where 语句 MariaDB ...

  2. centos 7 重新设置分区大小

    一.基础概念Cent0S 7默认启用LVM2(Logical Volume Manager),把机器的一块硬盘分为两个区sda1和sda2,其中分区sda1作为系统盘/boot挂载,少量空间:sda2 ...

  3. C基本语法

    分号 ; 在C程序中,分好是语句结束符,每个语句必须以分好结束,它表明一个逻辑实体的结束 例如: printf("Hello, World! \n"); ; 注释 // 单行注释 ...

  4. Android.mk文件官方使用说明

    本页介绍了 ndk-build 所使用的 Android.mk 编译文件的语法. 概览 Android.mk 文件位于项目 jni/ 目录的子目录中,用于向编译系统描述源文件和共享库.它实际上是编译系 ...

  5. NOIP2018 填数游戏 搜索、DP

    LOJ 感觉这个题十分好玩于是诈尸更博.一年之前的做题心得只有这道题还记得清楚-- 设输入为\(n,m\)时的答案为\(f(n,m)\),首先\(f(n,m)=f(m,n)\)所以接下来默认\(n \ ...

  6. jspatch功能解析

    一.三个模型: 1.补丁:运行时结构维护模型: 2.通信模型 3.解释模型:运行时 二.js.oc分层解释调用 js模块与oc模块的关系 1.oc调用js的配置信息完成配置: 2.oc运行时重定位到j ...

  7. 二.HTML

    1.HTML 1. <head></head>标签 <!DOCTYPE html> <!--统一规范--> <!----> <html ...

  8. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  9. tomcat重启session不失效问题

    本地写代码每次重启都要重新登录浪费了很多时间,如何重启不用重新登录呢,只要让tomcat在关闭时将session写入文件中,在启动时从文件中读取session即可. 只需在conf/context.x ...

  10. react 爬坑记录

    1.父子组件优化其一发生render条件:数据改变(state或者props改变),有时子组件会过多render.这时可在子组件里面的生命周期钩子里执行 shouldComponentUpdate(n ...