《劍指offer》:[53]正則表示式匹配
阿新 • • 發佈:2019-01-05
題目:請實現一個函式用來匹配包括’.’和’‘的正則表示式。模式中的字元’.’表示任意一個字元,而’‘表示它前面的字元可以出現任意次(包含0次)。在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串”aaa”與模式”a.a”和”ab*ac*a”匹配,但是與”aa.a”和”ab*a”均不匹配。
分析;常規中,如果是普通的兩個字串,那很簡單,我們直接進行對比就可以了,這裡又是要求匹配是指字串的所有字元匹配整個模式,所以只要直接挨個比較就可以了,如果都相等則返回true;否則返回false;可是這個題目來了一個'.'和'*'兩個比較煩人的東西,它改變了遊戲的規則。把遊戲變的複雜多變。
首先要明確'.'確定了字元的個數為1,並且為任意;'*'可以確定它前面的字元的個數包括0次;
第一種情況:當模式的第二個字元不是'*'的時候,如果字串的第一個字元和模式串的第一個字元相等,則都向後移動一個,匹配剩下的字串和模式串。如果不等則直接返回false;
第二種情況:當模式的第二個字元是'*'的時候,這時候就稍複雜點兒,因為這時候存在不同的幾種匹配方式:以字串"aaa"與模式"ab*ac*a"匹配為例:
1、如果模式串中的字元和字串中的字元不等如(a),且模式串的第二個字元為'*'。
(1)可以選擇在模式串上向後移動兩個字元,忽略掉b和*,因為'*'可以匹配0個字元,字串str保持不變;
(2)可以選擇越過'*','*'前的a當作有效的字元,且數量為1,str++;
(3)可以選擇模式串pattern不變,因為‘*’前的a可以任意數量的,並且和字串str相等,只需要str++即可;
分析;常規中,如果是普通的兩個字串,那很簡單,我們直接進行對比就可以了,這裡又是要求匹配是指字串的所有字元匹配整個模式,所以只要直接挨個比較就可以了,如果都相等則返回true;否則返回false;可是這個題目來了一個'.'和'*'兩個比較煩人的東西,它改變了遊戲的規則。把遊戲變的複雜多變。
首先要明確'.'確定了字元的個數為1,並且為任意;'*'可以確定它前面的字元的個數包括0次;
第一種情況:當模式的第二個字元不是'*'的時候,如果字串的第一個字元和模式串的第一個字元相等,則都向後移動一個,匹配剩下的字串和模式串。如果不等則直接返回false;
第二種情況:當模式的第二個字元是'*'的時候,這時候就稍複雜點兒,因為這時候存在不同的幾種匹配方式:以字串"aaa"與模式"ab*ac*a"匹配為例:
1、如果模式串中的字元和字串中的字元不等如(a),且模式串的第二個字元為'*'。
選擇只有一種:在模式串上向後移動兩個字元,忽略掉b和*,因為'*'可以匹配0個字元;如下圖:
(1)可以選擇在模式串上向後移動兩個字元,忽略掉b和*,因為'*'可以匹配0個字元,字串str保持不變;
(2)可以選擇越過'*','*'前的a當作有效的字元,且數量為1,str++;
(3)可以選擇模式串pattern不變,因為‘*’前的a可以任意數量的,並且和字串str相等,只需要str++即可;
具體如下圖所示:
#include <iostream> using namespace std; bool MatchCore(char *str,char *pattern) { if(*str=='\0' && *pattern=='\0') return true; if(*str!='\0' && *pattern=='\0') return false; if(*(pattern+1)=='*') { if(*pattern==*str || (*pattern=='.' && *str!='\0'))//將‘*’號忽略,‘*’前的作為一個有效的值; return MatchCore(str+1,pattern+2) || MatchCore(str+1,pattern) //‘*’號前可以出現任意個,所以pattern可以保持不變 || MatchCore(str,pattern+2);//忽略‘*’及‘*’號以前的字元; else return MatchCore(str,pattern+2);//因為‘*’ 號前的字元與*str不等,所以只能忽略*pattern字元一個選擇; } if(*str==*pattern || (*pattern=='.' && *str!='\0')) return MatchCore(str+1,pattern+1);//正常的字串比較; return false; } bool match(char *str,char *pattern) { if(str==NULL || pattern==NULL) return false; return MatchCore(str,pattern); } int main() { char str[]="aaa"; char *pattern[4]={"a.a","ab*ac*a","aa.a","ab*a"}; for(int i=0;i<4;i++) { if(match(str,pattern[i])) cout<<"The same!"<<endl; else cout<<"Not the same!"<<endl; } system("pause"); return 0; }
執行結果: