這一題從前往後事實上是很難找到辦法解決的,當正面無法解決問題時我們不妨換一個角度思考,從後往前匹配。
先來個大概的思路:噹噹前位置字符一樣,顯然最後是否能匹配取決於前面位置能否能匹配,所以要考慮前面位置是否匹配,而前面位置是否匹配,取決於那個位置值是否匹配(相同?. 等)和那個位置前面的值是否匹配。不難看出,這有點像反遞推。
接下來我們來考慮細的思路 :
當往前推超出了界限,我們需要特判。
當一個結束另一個未結束也需要特判。
若兩個都未結束:
若兩個相等,取決於當前位置的前一個位置是否能匹配
若是 ‘.’ ,則默認這個位置匹配了,跟上面是一樣的行爲
若是 ‘*’ ,那麼這個可以匹配 星號 前面字符0次,1次或者多次。只要有一種情況匹配上了都認爲可以匹配上。匹配0次時是否能匹配,則取決於模式串前兩位和待匹配串當前位是否能匹配。匹配1次,則情況變成了判斷模式串前一位(星號以前的那個字符)是否能與待匹配串的當前位匹配。匹配一次以上也是類似的情況,直接繼續往前遞推即可。
class Solution {
public:
bool IsAlpha(char c)
{
if(c >= 'a' && c <='z')
return true;
return false;
}
int AllStar(string &p,int k)
{
int temp = 0;
for(;k < p.length();++k)
if(p[k] != '*')
return 1;
return temp;
}
bool Match(string &s,string &p,int i1,int i2)
{
if(i1 < 0)
{
if(i2 < 0)
return true;
if(p[i2] != '*')
return false;
//如果i2還不等於0,那麼判斷前面是不是都是 字符*字符*...
return Match(s,p,i1,i2-2);//是*,則跳過它控制的字符繼續判斷
}
else if(i2 < 0)//i2結束了,但是l1還存在字符未匹配
return false;
//從後往前匹配,若是字母
if(IsAlpha(p[i2]))
{
if(s[i1]!=p[i2])
return false;
else
return Match(s,p,i1-1,i2-1);
}
else if(p[i2] == '.')
return Match(s,p,i1-1,i2-1);
else if(p[i2] == '*')//匹配前面的字符一次或者多次
{
//可匹配前面字符0次,或者1次,或者多次
// Match(s,p,i1,i2-2)//匹配0次
// Match(s,p,i1,i2-1)//匹配1次
// Match(s,p,i1-1,i2)//匹配多次
//若*號前面沒有字符
if(i2-1 < 0)
return false;
//匹配0次則無需管字符是不是對的,若匹配多次則需要判斷字符是否正確
//字符相同或者是.都算
return Match(s,p,i1,i2-2)||((s[i1] == p[i2-1] || p[i2-1] == '.') && Match(s,p,i1,i2-1))||((s[i1] == p[i2-1] || p[i2-1] == '.')&&Match(s,p,i1-1,i2));
}
return true;
}
bool isMatch(string s, string p) {
//.匹配任意字符
//*匹配前者0次或者多次
//s只含小寫字母
//p只含小寫字母和.*
return Match(s,p,s.length()-1,p.length()-1);
}
};