劍指offer——正規表示式匹配C++
難點有2
1:理清思路很難。2:"“的匹配有很多情況不知道到底是匹配幾個很難。
這裡我們用的是遞迴求解。分情況:先看pat的下一個是否為” * “,如果是,那麼又有兩種情況,當前位是否匹配,如果當前位匹配(可以用兩個字串當前字元相等或者pat當前字元為”.“來判斷),那麼要看接下來這個”“到底要匹配多少次了。第一種情況aa和aaa,匹配0次;第二種情況aa和aa,匹配1次;第三種情況aaab和a*b匹配多次。所以我們遞迴判斷每一種情況,只要有一種為true,那麼就是true,用||運算子。匹配0次是str不動,pat後移兩位…以此類推即可。
如果不能匹配,那麼 一定是匹配0次的,所以遞迴判斷str不變,pat後移兩位。
如果下一位不為"”,如果匹配(也是用兩個式子判斷)就均移一位。如果不匹配,就是false。
細節需要很注意,遞迴邊界以及一開始的邊界條件char * 是否為空用==’\0’來判斷,遞迴邊界是如果兩者同時走到底就是true,走到是當前位等於長度,而不是長度-1。如果pat走到底了,str沒到底,就是false。
還有一個細節是每次都要判斷是否會越界!這很重要,要放在&&的前面,後面才是取字元
class Solution {
public:
bool helpMatch(string str,int strIndex,string pattern, int patIndex){
//遞迴函式,遞迴邊界和遞迴式
//這裡的遞迴式分情況討論
//遞迴邊界就是一邊到底了,一邊沒到;或者兩邊都到了就是true
if(str.length() == strIndex && pattern.length() == patIndex){
return true;
}
//如果pat到底了,str沒到底,就是false,因為pat一般來說走的比較快
if(pattern.length() == patIndex && str.length() != strIndex){
return false;
}
//分情況,主要是看下一個是否為'*',先確保長度不會超,用&&
if(patIndex < pattern.length()-1 && pattern[patIndex+1] == '*'){
//又要分情況,如果當前位是匹配的,分3種情況
if(str[strIndex] == pattern[patIndex] || (strIndex != str.length() && pattern[patIndex] == '.')){
//第一種aa和a*aa,匹配0次,所以pat往後移兩位
//第二種ab和a*b,匹配1次,所以str往後1位,pat往後2位
//第三種aab和a*b,匹配多次,但是你不知道具體要匹配幾次,
//就一步一步往後推,str一位一位往後即可。遞迴要做的就是目前要做的事,後面的事交給後面的遞迴
//pat不變
return (helpMatch(str,strIndex,pattern,patIndex+2) ||
helpMatch(str,strIndex+1,pattern,patIndex+2)||
helpMatch(str,strIndex+1,pattern,patIndex));
}
else{
//如果是不匹配的,那麼只能匹配0次,str不動,pat後2位
return helpMatch(str,strIndex,pattern,patIndex+2);
}
}
//下一位不是*,正常匹配,如果不匹配,直接false
if(patIndex < pattern.length() && pattern[patIndex+1] != '*'){
if(str[strIndex] == pattern[patIndex] || (pattern[patIndex]=='.' && strIndex != str.length())){
return helpMatch(str,strIndex+1,pattern,patIndex+1);
}
}
return false;
}
bool match(char* str, char* pattern)
{
//主要是要分清楚所有情況
//str是字串,pattern是模式串
//先考慮只有".",沒有"*"的情況,如果當前字元相等或者pattern[j]=='.'都算匹配上了
//繼續考慮"*",如果在匹配的情況下
/*int i = 0, j = 0;
//先強轉
string a = str, b = pattern;
while(i < a.length()&& j < b.length()){
if(a[i] == b[j] || b[j] == '.'){
//匹配成功
if(j < b.length()-1 && b[j+1] == '*'){
//匹配0次或者匹配多次
}
else{
i++;
j++;
}
}
else{
if(j < b.length() - 1 && b[j+1] == '*'){
//只能匹配0次
}
else{
return false;
}
}
}
return i == j;*/
if(*str == '\0' && *pattern == '\0') return true;
if(*pattern == '\0') return false;
string a = str, b = pattern;
int strIndex = 0, patIndex = 0;
return helpMatch(a,strIndex,b,patIndex);
}
};
相關文章
- 【劍指 Offer 19. 正規表示式匹配】【Python】【動態規劃】Python動態規劃
- 正規表示式匹配原理
- [譯]正規表示式匹配
- 字串——正規表示式匹配字串
- iOS正規表示式匹配iOS
- 正規表示式支配匹配模式模式
- JavaScript匹配中文正規表示式JavaScript
- 模式匹配與正規表示式模式
- Swift 正規表示式匹配NSRegularExpressionSwiftExpress
- python 正規表示式匹配Python
- 匹配html標籤正規表示式HTML
- 匹配空白字元正規表示式字元
- 匹配 XML 檔案正規表示式XML
- 匹配 HTML 標籤正規表示式HTML
- leetcode - 正規表示式匹配LeetCode
- 匹配空行正規表示式程式碼
- 常用正規表示式匹配模式(java)模式Java
- JavaScript匹配註釋正規表示式JavaScript
- [JavaScript] 正規表示式單次匹配與多次匹配JavaScript
- 劍指Offer 表示數值的字串字串
- 匹配iphone手機序列正規表示式iPhone
- 匹配HTML註釋的正規表示式HTML
- 匹配A股程式碼的正規表示式
- 正規表示式匹配標點符號符號
- 匹配HTML標籤的正規表示式HTML
- 正規表示式匹配雙位元組字元字元
- js正規表示式如何匹配註釋JS
- 匹配javascript註釋的正規表示式JavaScript
- Oracle正規表示式匹配中文的方法Oracle
- 匹配正負小數正規表示式程式碼
- 《劍指offer》:[54]表示數值的字串字串
- 匹配視訊連結地址正規表示式
- 匹配純英文字元正規表示式字元
- 正規表示式教程之位置匹配詳解
- 常用正規表示式匹配程式碼介紹
- 正規表示式匹配使用者密碼密碼
- 演算法之字串——正規表示式匹配演算法字串
- 匹配中文正規表示式程式碼例項