正規表示式匹配問題的遞迴和動態規劃解法

2021-10-05 10:12:24 字數 1853 閱讀 6638

請實現乙個函式用來匹配包含』. 『和』 * 『的正規表示式。模式中的字元』.『表示任意乙個字元,而』 * '表示它前面的字元可以出現任意次(含0次)。在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串"aaa"與模式"a.a"和"abaca"匹配,但與"aa.a"和"ab*a"均不匹配。

使用遞迴來實現每一步的比較。看模式字串中當前位置的下乙個字元是否是「*」。

可以看出上述思路中關鍵是對 「*」 的判斷,對於a和a*的匹配有三種不同的情況,所以需要分開考慮,對應了星號前面的字元出現了多少次,三種情況用邏輯或並列比較,也就意味著三種情況中有一種滿足就算此次匹配成功。

class

solution

return

ismatchcore

(s,0

, p,0)

;}private

boolean

ismatchcore

(string s,

int sindex, string p,

int pindex)

// 模式不可以先結束,模式先結束肯定是不匹配的,但是字串如果先結束則不一定,

// 比如:a和aa*,字串中的指標先走到length的位置,但此時並沒有結束

// 自己做的時候沒考慮好,所以考慮問題一定要全面

if(sindex < s.

length()

&& pindex == p.

length()

)// 程式的主體是對模式判斷下乙個字元是否為「*」,

// 模式中的指標最多到倒數第二個。

if(pindex+

1< p.

length()

&& p.

charat

(pindex+1)

=='*'

)else

}// 模式的下乙個字元不是「*」,則直接比較字串和模式中當前位置的字元

if(sindex < s.

length()

&&(s.

charat

(sindex)

== p.

charat

(pindex)

|| p.

charat

(pindex)

=='.'))

return

false;}

}

遞迴解法在leetcode中耗時2000多ms,上述類似a和a*這樣的情況越短,遞迴的次數就越多,時間也就越慢。最近在學習動態規劃,發現題解中有大神給出了動態規劃的解法(鏈結在此:jerry的題解),故學習一波。

運用動態規劃,首先明確陣列含義。假設原字串為a1…m,模式串為b1…n,dp[i][j]表示a1…i和b1…j是否匹配,匹配為true,不匹配為false。

如何劃分子問題?判斷a1…i和b1…j是否匹配需要根據a1…i-1和b1…j-1來進行具體判斷。見下面的狀態轉移方程。

狀態轉移方程:

邊界條件:

動態規劃**如下,leetcode執行2ms!

class

solution

else

}else

// 第二種情況:星號前面的字元匹配上了

if(i>=

1&& j>=2&&

(s.charat

(i-1

)==p.

charat

(j-2

)|| p.

charat

(j-2)==

'.'))}

}}}return dp[m]

[n];

}}

正規表示式匹配 遞迴

請實現乙個函式用來匹配包含 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但與 aa.a 和 ab a 均不匹配。示例 1 輸入 s aa p ...

33 正規表示式匹配(遞迴)

給你乙個字串 s 和乙個字元規律 p,請你來實現乙個支援 和 的正規表示式匹配。匹配任意單個字元 匹配零個或多個前面的那乙個元素 所謂匹配,是要涵蓋 整個 字串 s的,而不是部分字串。s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 輸入 s ...

正規表示式 匹配

字串 void abtr quint32 ab 表示乙個正規表示式 template class bidirectionaliterator class allocator std allocator sub match bidirectionaliterator class match resul...