10. 正則表達式匹配(C++)---動態規劃解題

題目詳情

給你一個字符串 s 和一個字符規律 p,請你來實現一個支持 '.' 和 '*' 的正則表達式匹配。

'.' 匹配任意單個字符
'*' 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。
 

說明:

  • s 可能爲空,且只包含從 a-z 的小寫字母。
  • p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。
     

示例 1:

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


示例 2:

輸入:
s = "aa"
p = "a*"
輸出: true
解釋: 因爲 '*' 代表可以匹配零個或多個前面的那一個元素, 在這裏前面的元素就是 'a'。因此,字符串 "aa" 可被視爲 'a' 重複了一次。

示例 3:

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


示例 4:

輸入:
s = "aab"
p = "c*a*b"
輸出: true
解釋: 因爲 '*' 表示零個或多個,這裏 'c' 爲 0 個, 'a' 被重複一次。因此可以匹配字符串 "aab"。


示例 5:

輸入:
s = "mississippi"
p = "mis*is*p*."
輸出: false



——題目難度:困難

 




要解這道力扣困難題,即使是參考大神們的代碼思路 也得想半天呀...
不過也學到了很多,發現這道題目可以用動態規劃來解題,比較核心的點爲:用 dp[i][j] 表示 s 的前 i 個是否能被 p 的前 j 個匹配,然後圍繞此dp數組解題即可。

 



-下面解題代碼

class Solution {
public:
    bool isMatch(string s, string p) {
        int sLen = s.size();
        int pLen = p.size();
        if (pLen == 0) {
        	return sLen == 0? true : false;
        }
        
        vector<bool> tmp(pLen + 1, false);
        vector<vector<bool>> dp(sLen +1, tmp); //dp[i][j] 表示 s 的前 i 個是否能被 p 的前 j 個匹配
        dp[0][0] = true; //s 的前 0 個 肯定可以被 p 的前 0 個匹配
        
        if (sLen != 0 && (p[0] == s[0] || p[0] == '.')) {
        	dp[1][1] = true;
        }
        
        //初始化情況:s爲空,p爲 .*.* 的情況
        //也爲下面的遍歷匹配做準備工作 
        for(int i=1; i < pLen; i++)
        {
        	if(p[i] == '*' && dp[0][i - 1]) {
        		dp[0][i + 1] = true;
        	}
        }
        
        for(int i=0; i < sLen; i++)
        {
        	for(int j=1; j < pLen; j++)
        	{
        		/*p[j]不爲'*'的情況*/
        		if (p[j] == s[i] || p[j] == '.') { 
        		
					dp[i + 1][j + 1] = dp[i][j];
					
				} 
				
				/*p[j]爲'*'的情況*/
				if(p[j] == '*') {
					
					if (p[j - 1] == s[i] || p[j - 1] == '.') { //如果前一個元素匹配 或者 爲任意元素
					
						dp[i + 1][j + 1] = (dp[i + 1][j - 1] || dp[i][j + 1]);
						//看 dp[i + 1][j - 1]的情況:也就是 將當前組合(.*)扔掉,看 dp[i + 1][j - 1] 的情況
						
					} else { //如果前一個元素不匹配 且不爲任意元素
						dp[i + 1][j + 1] = dp[i + 1][j - 1]; //如果前一個元素不匹配,只能 將該組合(.*)扔掉 來看情況
					}
				}
			
			}
		}
					
		return dp[sLen][pLen];				
    }
};

結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章