[劍指Offer] 19_正則表示式匹配
題目
請實現一個函式來匹配包含’.‘和’*‘的正則表示式。模式中的字元’.‘表示任意一個字元,而’*'表示它前面的字元可以出現任意次(含0次)。在本題中,匹配是指字串中的所有字元匹配整個模式。
例:
字串"aaa"與模式"a.a"和“ab*ac*a">匹配,但與"aa.a"和"ab*a"均不匹配。
思路
-
正面暴力深度優先搜尋。書上給出的解法。注意使用遞迴以便處理回溯。(a*a匹配aaa)
約定:待匹配字串為 s ,匹配模式為 p 。
當p超界時,判斷s是否已經全部匹配;
當s超界時,判斷p是否已經全部匹配;若不是,剩下的p是否可以匹配空字串。
當p == s 或者 p == .,過;
當p+1 == *,判斷p == s
不匹配,移動向匹配p+2。
匹配, 1-【s繼續向下匹配p-1】,2-【此次s匹配下面移動向匹配p+2】,3-【此次不匹配s直接移動向下匹配p+2】(例如a*ab匹配ab,即使a*可以匹配a對於整個字串此時應當選擇跳過)。
程式執行到這裡時,將會進行深度優先搜尋,試探上述三個情況,當遇見匹配a*a*a*a*a*b匹配aaaaac,時間複雜度將爆炸O(3^n)。然而這裡三個情況是有重疊的。下一個思路將會講解。- 時間複雜度:O(3^n)
- 空間複雜度:O(n) 最深遞迴
-
從後暴力深度優先搜尋。因為*出現在字元後面,如果從前向後遍歷,將會需要判斷字元後一個是否為 * 。同時分析思路1,對於出現 * 時的策略,2-【此次s匹配下面移動向匹配p+2】,3-【此次不匹配s直接移動向下匹配p+2】,是同一種情況。因為當出現3時,即為選擇1->2策略。所以對於 * 根本上只有2種處理,1-【繼續匹配】2-【跳過】。
此外,對於邊界書上的程式碼只考慮 s 是否超界時,p是否超界,對於p未超界情況,未分開討論,導致複雜度增加。- 時間複雜度:O(2^n)
- 空間複雜度:O(n) 最深遞迴
-
一開始沒想到可以動態規劃,還是題目做的少了。在閱讀Github上的解法我才明白這道題和LCS問題是類似的。
觀察模式能匹配時,必有模式的子模式匹配字串的子串。
例如,aa*b 匹配 ab,必有aa*匹配a,必有 a 匹配 a。
令字串 模式
假設 可以被模式 匹配
1.如果 匹配 ,則 匹配
2.如果 不匹配 , 則 匹配 且 匹配
3.如果 不匹配 ,則有 匹配 , 匹配