原本準備在暑假學習DP算法的,但最近感覺心裏少了什麼東西一樣,原來是自己不瞭解DP 導致的空落感,所以把官方的答案 和 度孃的解釋看了一遍,自己用 Debug 測試了一下,把自己的所想分享給大家 . . .
.
前文鏈接(遞歸解決正則表達式匹配):
此文章主要講解 DP的運行過程 !!!
題目:
給你一個字符串 s 和一個字符規律 p,請你來實現一個支持 ‘.’ 和 ‘*’ 的正則表達式匹配。
‘.’ 匹配任意單個字符
‘*’ 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。
說明:
s 可能爲空,且只包含從 a-z 的小寫字母。
p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。
示例此處就不粘貼了
官方代碼如下:
官方用DP思想寫的代碼中,重要的地方我已經用紅色方框標明瞭起來,下來我們來討論一下他們的作用 . . .
官方思想解析:
.
上面的解析中畫紅色框的部分與上面代碼中畫框的部分相對應 . . .
切記程序中對數組下標的處理( + 1 ?)
.
下面我來帶大家走進 Debug的世界,看看這個 DP 是怎麼工作的 . . .
DP 過程解析
我們使用下面的數據進行測試(大家也可以試試別的數據):1) 首先根據上面官方解析,我們準備一個容器,準備工作到位:
vector <vector<int> > vec(m + 1, vector<int>(n + 1));
vec[0][0] = true;
此時的狀態圖如下所示:
我們的最終效果如下:
2) 遍歷容器裏的元素 vec[i][j]
(每個元素表示一個狀態,官方解析思想上面有):
for (size_t i = 0; i <= m; ++i)
{
for (size_t j = 1; j <= n; ++j)
{
}
}
這裏的 m是 s的大小,n是 p的大小 . . .
這裏的 i 是從 0 開始的,上面的截圖部分有誤,還請諒解 ^ _ ^
.
3)準備一個判斷對應字符是否相等的方法(這裏很佩服官方的作法,用的是 Lambda表達式):
auto JudgeIsNoMatch = [&s, &p](int i, int j) {
if (i == 0) // 如果當前匹配s的長度爲 0,則直接返回
return false;
if (p[j - 1] == '.') // . 可匹配萬物
return true;
return s[i - 1] == p[j - 1]; // 判斷是否相等
};
.
4)當前p中的判斷字符是否爲 * 處理的部分:
// 等於 * 時處理的步驟
if (p[j - 1] == '*') {
vec[i][j] |= vec[i][j - 2]; // 判斷是否可以捨棄 *號
// j 與 i 前的所有字符匹配,保存記錄判斷到最後
// 可以這個判斷有點萌幣,不急,看我下面的Debug 測試就知道了 )``^ _ ^``
if (JudgeIsNoMatch(i, j - 1)) {
vec[i][j] |= vec[i - 1][j]; // a* 要和 s中的 i - 1 個字符要匹配
}
}
// 不等於 * 時處理的步驟
else {
// 直接判斷是否相等
if (JudgeIsNoMatch(i, j)) {
// i - 1 個 s中的字符 要和 j - 1 個 p中的字符要相等
vec[i][j] |= vec[i - 1][j - 1];
}
}
.
5)開始我們 Debug測試,看看我們的最終圖是如何求出解來的:
我們最終的結果就是判斷
vec[m][n] 是否爲 1
就行了,說明我們已經完美的匹配結束了 . . .
.
return vec[m][n];
.
Debug 測試結果
- 使用斷點,調試程序:
.
- 當 i = 1,j = 1 時,執行 else 語句:
因爲 vec[0][0] = 1,所以 vec[1][1] |= vec[0][0] == 1;
.
此時,狀態圖如下:
.
- 當 i = 2,j = 2 時,執行 else 語句:
原理與上面相同
.
-
當 i = 2,j = 4 時,執行 if 中的語句:
此時,這句代碼將起到作用:
vec[i][j] |= vec[i][j - 2];
此處的 a* 將捨棄,這樣才能滿足題目的意思(所做的一切都是爲下面做服務) . . .
-
當 i = 3,j = 3 時,與 2、3 是相同的:
.
- 當 i = 3,j = 4時,執行下面的語句:
執行的代碼是:
vec[i][j] |= vec[i - 1][j];
因爲 if中判斷成功了,說明相應的字符是相同的,並且之間的字符也判斷相同了(vec[i - 1][j])證明 . . .
.
- 當 i = 4, j = 4時,同 6 相同:
.
文章可能有許多寫的不好的地方,還請大家諒解,因爲我太困了 (>_<)
.