剛好最近在學編譯原理
有點想按照語法分析寫。。不過用不着
因為知道正則表達式對一個串可能有多種匹配方法,所以要准備好回溯。
有最優子結構,一段s由一段p生成,於是dp。
常規思路是從前開始逐個字符匹配
這里想一下,倒着匹配考慮的情況少一些(其實是想正寫發現太難了。。。囧)
dp[i][j]表示s[i:]可以由p[j:]生成(匹配。)於是就只需要考慮0-i-1,0-j-1的匹配
match是某個生成式的字符(x或.,而不是*)與某個串某個字符匹配
如s=abbb,p=ab*
bbb與b*匹配,每一個b都與b*的b匹match。
若匹配只有兩種情況,單個.匹配和x*匹配。
具體處理
單個.匹配 dp[i][j] = first_match && dp[i+1][j+1]; //可能匹配到(match==true),則推進一位
x*匹配 dp[i][j] = dp[i][j+2] ||match && dp[i+1][j]; //兩種情況,可能使用p[j],匹配不到,dp[i][j] = dp[i][j+2] ; 或可以匹配,則dp[i][j] =dp[i+1][j],一個個字符推進(i+1)
復雜度分析看官方題解吧
注意初始化
沒加false初始化
跑某個例子
"mississippi"
"mis*is*p*."
報錯
dp[i][j] = match && dp[i+1][j+1];
load of value 48, which is not a valid value for type 'bool'
class Solution { public: bool isMatch(string s, string p) { bool dp[s.length() + 1][p.length() + 1]; for(int i=0;i<=s.length();i++) for(int j=0;j<=p.length();j++) dp[i][j]=false; dp[s.length()][p.length()] = true; for (int i = s.length(); i >= 0; i--){ for (int j = p.length() - 1; j >= 0; j--){ bool match = (i < s.length() &&(p[j] == s[i] ||p[j] == '.')); if (j + 1 < p.length() && p[j+1] == '*'){ //x*匹配 dp[i][j] = dp[i][j+2] || match && dp[i+1][j]; } else { //單個.匹配 dp[i][j] = match && dp[i+1][j+1]; } } } return dp[0][0]; } };