日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

困难动态规划系列、经典的正则表达式和通配符匹配问题(难题)

發布時間:2024/10/8 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 困难动态规划系列、经典的正则表达式和通配符匹配问题(难题) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2020/10/24、 周六、今天又是奮斗的一天。

正則表達式(Regular Expression, RE)就是一組定義某種搜索模式(pattern)的字符。

文章目錄

  • Leetcode 10 正則表達式匹配
  • Leetcode 44 通配符匹配

Leetcode 10 正則表達式匹配

題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/regular-expression-matching/

* : 前一個字符匹配0次或任意多次 . : 匹配除了換行符以外任意一個字符示例 1 輸入:s = "aa", p = "a" 輸出:false 示例 2 輸入:s = "aa", p = "a*" 輸出:true 示例 3 輸入:s = "ab", p = ".*" 輸出:true

當然你可以直接在程序里面調用正則表達式的庫?但你這樣面試絕對過不了的

我覺得應該想一想,p的子串和s的子串有沒有聯系?當然有!

大家可以先看下Leetcode官方題解

我們先定義一個二維數組dp,其中dp[i][j]表示的是p的前j個字符和s的前i個字符匹配的結果。

取二維數組dp[i][j],表示當s[i]至p[j]為止是否匹配

若dp[i][j]匹配則前一位即dp[i-1][j-1]一定匹配

當前兩個字符是否匹配,取決于兩個字符是否相等或者模式串p中的對應字符是否為單字符匹配通配符「.」

因此s[i] == p[j] or p[j] == '.',很容易得到 dp[i][j] = dp[i-1][j-1] = True

處理特殊情況,當前模式串的對應字符為*時=,如果星號前一個字符匹配不上p[j-1] != s[i]:,星號匹配了 0 次,應忽略這兩個字符,看p[j-2]和 s[i] 是否匹配。 這時 dp[i][j] = dp[i][j-2]

如果匹配成功或者*的前面是.,也就是p[j-1] == s[i] or p[j-1] == '.':,

比如 abbb 和 ab*,那么dp[i][j] = dp[i-1][j],如果下一次繼續遇到,則一直回溯下去。

相反出現了abbb和a.*,同樣dp[i][j] = dp[i-1][j]。

這里會出現一個Bug,就是ab 和 abb*。我們一定認為s比p長嗎?遇到這種情況,就是 dp[i][j] = dp[i][j-2],直接去除.*。

動態規劃最重要的是寫出轉移方程,這里,直接給出結果,這個題目中,難點就在于處理 . 和*兩個符號。

class Solution:def isMatch(self, s: str, p: str) -> bool:m, n = len(s), len(p)# 配對s[i]和s[j]def matches(i, j):if i == 0:return Falseif p[j - 1] == '.':return Truereturn s[i - 1] == p[j - 1]dp = [[False] * (n + 1) for _ in range(m + 1)]dp[0][0] = Truefor i in range(m + 1):for j in range(1, n + 1):if p[j - 1] == "*":dp[i][j] = dp[i][j] | dp[i][j - 2]if matches(i, j - 1):dp[i][j] = dp[i][j] | dp[i - 1][j]else:if matches(i, j):dp[i][j] = dp[i][j] | dp[i - 1][j - 1]return dp[m][n]

下面是在Leetcode中逛見的簡單高效的代碼。原則在是在遞歸代碼上進行優化。

class Solution:def isMatch(self, s: str, p: str) -> bool:memo = dict()len_s = len(s)len_p = len(p)def dp(i, j):# s從i起,p從j起,是否匹配if (i, j) in memo: return memo[(i,j)]if j == len_p: return i == len_sfirst_match = i < len_s and p[j] in {s[i], '.'}if j <= len_p - 2 and p[j+1] == '*':# 遇到*, 不匹配,p往后s不動;匹配,s往后p不動memo[(i, j)] = dp(i, j+2) or \(first_match and dp(i+1, j))else:memo[(i, j)] = first_match and dp(i+1, j+1)return memo[(i,j)]return dp(0,0)

在上面動態規劃,是將下面的暴力解的方法中,頻繁使用切片操作,復雜度高。在暴力解的基礎上,使用動態規劃的方法,定義變量 i,j 來記錄當前匹配到的位置,用 dp(i, j) 表示 s[i:] 和 p[j:] 是否能夠匹配,避免頻繁切片。這里也引入備忘錄的概念,用來避免重復的運算。

class Solution:def isMatch(self, s: str, p: str) -> bool:if not p:return not s# 解決.first_match = bool(s) and p[0] in {s[0], '.'}# 解決*if len(p) >= 2 and p[1]=="*":return self.isMatch(s, p[2:]) or first_match and self.isMatch(s[1:], p)else:return first_match and self.isMatch(s[1:], p[1:])

Leetcode 44 通配符匹配

題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/wildcard-matching/

給定一個字符串 (s) 和一個字符模式 § ,實現一個支持 ‘?’ 和 ‘*’ 的通配符匹配。

'?' 可以匹配任何單個字符。 '*' 可以匹配任意字符串(包括空字符串)。輸入: s = "aa" p = "a" 輸出: false 輸入: s = "aa" p = "*" 輸出: true 輸入: s = "adceb" p = "*a*b" 輸出: true 輸入: s = "acdcb" p = "a*c?b" 輸出: false

兩個字符串在一起的題目,其他都不要想,直接考慮動態規劃,而且是字符串匹配題型。首先是構造動態規劃轉移方程。

dp[ i ][ j ]表示s的前i位和p的前j位是否匹配。那么轉移方程首先考慮的是s的第i位和p的第j位的取值情況,當然這里的s都是字母,關鍵就是p的第j位,p的第j位可以是字母可以是?,可以是*。轉移方程如下所示:(s[ i ]表示s的第i位的字母)

if ( s[ i ] == p[ j ]) 那么dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ]if ( s[ i ] != p[ j ])p[ j ]是字母 :dp[ i ][ j ] = false;p[ j ]是?:dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ]p[ j ]是* :dp[ i ][ j ] = dp[ i ][ j - 1 ] || dp[ m ][ j - 1 ] m從[ 1 , i - 1]遍歷

這里就是*的概念不同,上面是配對前一個字符匹配0次或任意多次,而這里是可以匹配任意字符串(包括空字符串)

最關鍵是p的第j位是*時,*能匹配任意字符串,空字符串也能匹配,所以此時應該遍歷*匹配s的前面所有情況,也就是*能匹配空字符串,能匹配s的后1位,后2位…甚至匹配整個s字符串,這里為了提高運算效率,只要dp[ i ][ j ]為true就停止遍歷。

這題相比第10題正則匹配式,簡單些。那題分析起來比較麻煩。

class Solution:def isMatch(self, s: str, p: str) -> bool:m, n = len(s), len(p)dp = [[False] * (n + 1) for _ in range(m + 1)]dp[0][0] = Truefor i in range(1, n + 1):if p[i - 1] == '*':dp[0][i] = Trueelse:breakfor i in range(1, m + 1):for j in range(1, n + 1):if p[j - 1] == '*':dp[i][j] = dp[i][j - 1] or dp[i - 1][j]elif p[j - 1] == '?' or s[i - 1] == p[j - 1]:dp[i][j] = dp[i - 1][j - 1] return dp[m][n]
請一鍵三連!!!!!

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的困难动态规划系列、经典的正则表达式和通配符匹配问题(难题)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 香港一级纯黄大片 | 神马久久久久久久久久久 | 天堂影视av | 丝瓜av| 久热色| 毛片av网站 | 97麻豆| 欧美 日韩 高清 | 欧美另类极品videosbest使用方法 | 欧美成人综合色 | 中文字幕日韩电影 | 国产中文一区 | av在线免费观看网站 | 成人av视屏| 亚洲中文无码av在线 | 全黄性高潮 | 伊人精品一区二区三区 | 国产一区欧美 | 色老头影视 | jiuse九色 | 中文字字幕一区二区三区四区五区 | 97av在线播放 | 求毛片网站| 亚洲一级黄色片 | 日韩精品一级 | 亚洲一区二区三区激情 | 日韩av网站在线 | 嫩草精品 | 999午夜| 亚洲精品久久久久中文字幕二区 | 国语av在线| 国产网站精品 | 色av色| 一级黄色片免费在线观看 | 一级二级三级黄色片 | 温柔少妇的高潮呻吟 | 黄色片在线免费观看 | 欧美一区二区三区四区五区六区 | 国产一区二区免费在线观看 | 二级黄色录像 | 国产偷人妻精品一区二区在线 | 狠狠干2021 | 永久免费AV无码网站韩国毛片 | 精品久久免费 | 无码人妻精品丰满熟人区 | 日韩精品无码一区二区三区 | 爱豆国产剧免费观看大全剧集 | 精品乱子伦 | 亚洲免费综合 | 91天天射| 自拍偷拍国产 | 国产极品美女高潮无套在线观看 | 国产15页 | 久热精品视频在线观看 | 99热6这里只有精品 三级av在线免费观看 | 欧美激情视频一区二区 | 成人性视频sm.| 久久情趣视频 | 蜜桃成人网 | 日本大胆人体视频 | 美女试爆场恐怖电影在线观看 | 国产主播精品 | 欧美视频一区在线观看 | 日韩av一二三区 | 成人在线免费高清视频 | 欧美美女性生活视频 | 福利视频第一页 | 久久爱一区二区 | 色播激情网| 国产精品激情偷乱一区二区∴ | 国偷自拍第113页 | 黄色字幕网 | 精品无码国产一区二区三区av | 欧美变态口味重另类在线视频 | 麻豆一级片 | 成人精品免费网站 | yy6080午夜 | 玖玖国产精品视频 | 久久天堂 | 天堂影视av | 男女裸体无遮挡做爰 | 国产卡一卡二在线 | 国产小视频你懂的 | 久久久久久久久久一级 | 欧美色视频在线观看 | 国产一区二区视频在线 | 西西444www无码大胆 | 中文字幕免费高清在线观看 | 国产性生活片 | 国产又大又长又粗 | 成年女人18级毛片毛片免费 | 影音先锋国产 | 丰满人妻一区二区三区免费视频 | 国产www免费 | 日本视频一区二区三区 | 亚洲综合av一区二区三区 | 日韩在线第二页 | 欧美啪啪一区二区 | 在线播放av片|