最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

動態(tài)遞歸之正則表達(dá)式實(shí)戰(zhàn)案例(含Java代碼)

 更新時間:2026年05月08日 10:10:09   作者:納蘭青華  
正則表達(dá)式是對字符串的一種描述方法,即使用特定的信息來描述字符串格式的一種方式,這篇文章主要介紹了動態(tài)遞歸之正則表達(dá)式的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

題目:正則表達(dá)式

給你一個字符串 s 和一個字符規(guī)律 p,請你來實(shí)現(xiàn)一個支持 ‘.’ 和 ‘*’ 的正則表達(dá)式匹配。

‘.’ 匹配任意單個字符
‘*’ 匹配零個或多個前面的那一個元素

所謂匹配,是要涵蓋 整個 字符串 s 的,而不是部分字符串。

示例 1:

輸入:s = “aa”, p = “a”
輸出:false
解釋:“a” 無法匹配 “aa” 整個字符串。

示例 2:

輸入:s = “aa”, p = “a*”
輸出:true
解釋:因?yàn)?‘*’ 代表可以匹配零個或多個前面的那一個元素, 在這里前面的元素就是 ‘a’。因此,字符串 “aa” 可被視為 ‘a’ 重復(fù)了一次。

示例 3:

輸入:s = “ab”, p = “."
輸出:true
解釋:".” 表示可匹配零個或多個(‘*’)任意字符(‘.’)。

提示:

1 <= s.length <= 20
1 <= p.length <= 20
s 只包含從 a-z 的小寫字母。
p 只包含從 a-z 的小寫字母,以及字符 . 和 *。

保證每次出現(xiàn)字符 * 時,前面都匹配到有效的字符

題解

方法一:帶記憶化遞歸

思路:

遞歸函數(shù) match(i, j) 表示字符串 s 從 i 開始到末尾的子串和模式 p 從 j 開始到末尾的子串是否匹配。
考慮以下情況:

  • 如果 j 已經(jīng)到達(dá) p 的末尾,那么只有當(dāng) i 也到達(dá) s 的末尾才匹配成功。
  • 首先檢查當(dāng)前第一個字符是否匹配:first_match = (i < s.length()) 且 (s.charAt(i) == p.charAt(j) 或 p.charAt(j) == ‘.’)
  • 如果下一個字符是 ‘*’ (即 j+1 < p.length() 且 p.charAt(j+1)==‘*’),那么有兩種情況:
          a. 匹配0個前面的字符:則跳過模式中的"x*"(即j+2),繼續(xù)匹配 match(i, j+2)
          b. 匹配1個或多個前面的字符:在第一個字符匹配的前提下,匹配s的下一個字符,模式保持不變(因?yàn)?可以匹配多個),即 match(i+1, j)
  • 否則,如果沒有’*',那么當(dāng)前字符必須匹配,然后遞歸匹配剩下的部分:match(i+1, j+1)
          但是注意:遞歸可能會出現(xiàn)重復(fù)子問題,所以效率可能不高,但作為解決方案之一。
public class RegularExpMatch {
    // 使用Map存儲已計算的結(jié)果,避免重復(fù)計算
    private Map<String, Boolean> memo = new HashMap<>();
    public boolean isMatch(String s, String p) {
        return dp(0, 0, s, p);
    }
    private boolean dp(int i, int j, String s, String p) {
        // 生成唯一鍵值對,用于記憶化存儲
        String key = i + "," + j;
        if (memo.containsKey(key)) {
            return memo.get(key);
        }
        // 模式串已用完
        if (j == p.length()) {
            return i == s.length();
        }
        // 檢查當(dāng)前字符是否匹配
        boolean firstMatch = (i < s.length()) &&
                (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
        boolean result;
        // 處理'*'的情況(需要確保j+1不越界)
        if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
            // 兩種情況:
            //1. 匹配0個字符(跳過當(dāng)前字符和*)即匹配0次,不消耗任何字符串字符
            //2. 匹配1個或多個字符(繼續(xù)匹配)
            result = dp(i, j + 2, s, p) || (firstMatch && dp(i + 1, j, s, p));
        } else {
            // 沒有'*',正常匹配下一個字符
            result = firstMatch && dp(i + 1, j + 1, s, p);
        }
        // 存儲計算結(jié)果   
        memo.put(key, result);
        return result;
    }
}

方法二:動態(tài)規(guī)劃

  • 初始化:空字符串匹配空模式
  • 處理模式開頭可能的"x*"匹配空字符串的情況
  • 狀態(tài)轉(zhuǎn)移分三種情況:
    • 普通字符匹配
    • '.'匹配任意字符
    • '*'的兩種處理方式(匹配0次或多次)
public boolean isMatch(String s, String p) {
   int m = s.length(), n = p.length();
   // dp[i][j]表示s的前i個字符和p的前j個字符是否匹配
   boolean[][] dp = new boolean[m + 1][n + 1];
   // 空字符串匹配空模式
   dp[0][0] = true;
   // 處理模式開頭可能有 "a*" 或 ".*" 的情況(匹配空字符串)
   for (int j = 2; j <= n; j++) {
       if (p.charAt(j - 1) == '*') {
           dp[0][j] = dp[0][j - 2]; // 跳過 "x*" 模式
       }
   }
   for (int i = 1; i <= m; i++) {
       for (int j = 1; j <= n; j++) {
           char sc = s.charAt(i - 1);
           char pc = p.charAt(j - 1);
           // 當(dāng)前字符匹配
           if (sc == pc || pc == '.') {
               //如果當(dāng)前字符匹配,此時的值為去掉當(dāng)前字符后是否匹配的值
               dp[i][j] = dp[i - 1][j - 1];
           }
           // 處理 '*' 的情況
           else if (pc == '*') {
               char prev = p.charAt(j - 2); // '*' 前面的字符,注意i和j表示的是dp表的下標(biāo),不是字符串下標(biāo),字符值下標(biāo)還需要-1
               // 1. 匹配0個字符(跳過 "x*" 模式)
               dp[i][j] = dp[i][j - 2];
               // 2. 匹配1個或多個字符(如果前一個字符匹配)
               if (prev == '.' || prev == sc) {
                   dp[i][j] = dp[i][j] || dp[i - 1][j]; //表示如果匹配0個字符成立就直接返回true了,否則再匹配1個或多個字符
               }
           }
       }
   }
   return dp[m][n];
}

考慮字符串 s = “abcde” 和模式 p = “abcc*d*.*de”,我們使用動態(tài)規(guī)劃來解決匹配問題。動態(tài)規(guī)劃表如下:
dp[i][j] 表示 s 的前 i 個字符與 p 的前 j 個字符是否匹配。

s\p01:a2:b3:c4:c5:*6:d7:*8:.9:*10:d11:e
0TFFFFFFFFFFF
1:aFTFFFFFFFFFF
2:bFFTFFFFFFFFF
3:cFFFTFTFTFTFF
4:dFFFFFFTTFTTF
5:eFFFFFFFFFFFT

總結(jié):

匹配0真的難繃,匹配0個我以為只是’*‘沒了但其前面的元素還在,結(jié)果是’*'和前面一個元素都沒了?。。?!

到此這篇關(guān)于動態(tài)遞歸之正則表達(dá)式的文章就介紹到這了,更多相關(guān)動態(tài)遞歸之正則表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot集成Nacos實(shí)現(xiàn)注冊中心與配置中心流程詳解

    SpringBoot集成Nacos實(shí)現(xiàn)注冊中心與配置中心流程詳解

    這篇文章主要介紹了SpringBoot集成Nacos實(shí)現(xiàn)注冊中心與配置中心流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Java中將String類型轉(zhuǎn)換為int類型的五種方法及常見問題分析

    Java中將String類型轉(zhuǎn)換為int類型的五種方法及常見問題分析

    在Java中將String類型轉(zhuǎn)換為int類型是一個常見的操作,因?yàn)樵趯?shí)際開發(fā)中,我們經(jīng)常需要從用戶輸入或者外部數(shù)據(jù)源中獲取字符串形式的數(shù)字,并將其轉(zhuǎn)換為整數(shù)進(jìn)行計算和處理,在Java中,有幾種方法可以實(shí)現(xiàn)這種轉(zhuǎn)換,下面我將逐一介紹這些方法,需要的朋友可以參考下
    2025-06-06
  • Java?I/O流使用示例詳解

    Java?I/O流使用示例詳解

    Java.io?包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目標(biāo)。本文將通過示例為大家詳細(xì)講講?I/O流的使用教程,需要的可以參考一下
    2022-08-08
  • 使用idea解決maven依賴沖突的問題

    使用idea解決maven依賴沖突的問題

    這篇文章主要介紹了使用idea解決maven依賴沖突,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot幾種常用的接口日期格式化方法

    SpringBoot幾種常用的接口日期格式化方法

    在 Springboot 應(yīng)用程序中,日期時間格式化處理是非常重要的一方面,本文將總結(jié)SpringBoot幾種常用的接口日期格式化方法,通過示例代碼介紹了非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2024-11-11
  • 詳解UDP協(xié)議格式及在java中的使用

    詳解UDP協(xié)議格式及在java中的使用

    這篇文章主要介紹了UDP協(xié)議格式及在java中的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • Java自動化測試中多數(shù)據(jù)源的切換(實(shí)例講解)

    Java自動化測試中多數(shù)據(jù)源的切換(實(shí)例講解)

    下面小編就為大家?guī)硪黄狫ava自動化測試中多數(shù)據(jù)源的切換(實(shí)例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Spring 框架需要的 jar 包解析與使用小結(jié)

    Spring 框架需要的 jar 包解析與使用小結(jié)

    本文總結(jié)Spring4.x項(xiàng)目的核心jar包作用及最小依賴組合,涵蓋IoC容器、AOP、Web、數(shù)據(jù)訪問等模塊,建議使用Maven/Gradle管理依賴,避免手動配置導(dǎo)致版本混亂,助力開發(fā)者高效維護(hù)Spring應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • Spring中自帶的@Schedule實(shí)現(xiàn)自動任務(wù)的過程解析

    Spring中自帶的@Schedule實(shí)現(xiàn)自動任務(wù)的過程解析

    這篇文章主要介紹了關(guān)于Spring中自帶的@Schedule實(shí)現(xiàn)自動任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Java集合之整體結(jié)構(gòu)

    Java集合之整體結(jié)構(gòu)

    Java中集合類是Java編程中使用最頻繁、最方便的類。接下來通過本文給大家介紹Java集合之整體結(jié)構(gòu),一起看看吧
    2016-05-05

最新評論

栾城县| 芜湖县| 旌德县| 四会市| 类乌齐县| 阿克| 手游| 米易县| 卢氏县| 白沙| 临湘市| 神池县| 定州市| 潞城市| 青河县| 阿拉善左旗| 潼南县| 新沂市| 临邑县| 雷山县| 苍山县| 林州市| 肃宁县| 霍林郭勒市| 武平县| 铜陵市| 宜昌市| 南平市| 平凉市| 万安县| 仁布县| 米林县| 汕尾市| 苏州市| 灵川县| 香河县| 双鸭山市| 忻州市| 苏尼特右旗| 茂名市| 乐昌市|