萬用字元匹配字串

2021-06-21 14:02:29 字數 3496 閱讀 1794

問題:實現支援?和*兩個萬用字元的字串匹配函式。

implement wildcard pattern matching with support for'?'and'*'.

'?' matches any single character.

'*' matches any sequence of characters (including the empty sequence).

the matching should cover the entire input string (not partial).

the function prototype should be:

bool ismatch(const char *s, const char *p)

some examples:

ismatch("aa","a") → false

ismatch("aa","aa") → true

ismatch("aaa","aa") → false

ismatch("aa", "*") → true

ismatch("aa", "a*") → true

ismatch("ab", "?*") → true

ismatch("aab", "c*a*b") → false

回憶一下類似的乙個問題《簡單的正規表示式匹配 regular expression matching》,注意其中的區別:兩個問題中*所具備的匹配能力是不同的。

思路一:遞迴求解。雖然已經把重複出現的*過濾,不過超時了。

[cpp]view plain

copy

print

?class solution   

bool isvalid(const

char *s, const

char *p)  

else

return isvalid(s, p);  

}  }  

};  

class solution 

bool isvalid(const char *s, const char *p)

else

return isvalid(s, p);}}

};

思路二:

動態規劃法。

設定狀態量h[pn+1][sn+1]。h[i][j]表示p的前i個字元能否匹配成功s的前j個字元。

遞推關係:如果h[i-1][j-1]=1,若p[i]='?'或者p[i]==s[j],那麼h[i][j]為1;若p[i]='*',那麼h[i][j-1]到h[i][sn]都為1。

初始條件:h[0][0]=1。

注意:必須要提前把不可能匹配的情況排除,否則會超時。當p串中非*字元的個數大於0且少於s串的字元個數時,匹配不可能成功。

[cpp]view plain

copy

print

?class solution   

int pn = p1 - p;  

p1 = s;  

while(*p1 != 0)  

p1++;  

int sn = p1 - s;  

if(pn == stars && stars > 0) //p串中只有*的情況

return

true;  

if(pn - stars > sn) //p串中非*字元的個數少於s串,不可能匹配

return

false;  

int h[pn+1][sn+1];  

memset(h,0 ,sizeof(h));  

h[0][0] = 1;  

for(int i=1;i<=pn;i++)  

for(int i=1;i<=pn;i++)  

else

if(p[i-1] == '*')  

}  }  }  

//當p串以*結尾時,與s的匹配有可能提前結束。

int last;  

for(last=pn;last>=0;last--)  

if(h[last][sn] == 1)  

break;  

last++;  

while(last<=pn && p[last-1] == '*')  

last++;  

if(last == pn+1)  

return

true;  

return h[pn][sn] == 1;  

}  };  

class solution 

int pn = p1 - p;

p1 = s;

while(*p1 != 0)

p1++;

int sn = p1 - s;

if(pn == stars && stars > 0) //p串中只有*的情況

return true;

if(pn - stars > sn) //p串中非*字元的個數少於s串,不可能匹配

return false;

int h[pn+1][sn+1];

memset(h,0 ,sizeof(h));

h[0][0] = 1;

for(int i=1;i<=pn;i++)

for(int i=1;i<=pn;i++)

else if(p[i-1] == '*')}}

}//當p串以*結尾時,與s的匹配有可能提前結束。

int last;

for(last=pn;last>=0;last--)

if(h[last][sn] == 1)

break;

last++;

while(last<=pn && p[last-1] == '*')

last++;

if(last == pn+1)

return true;

return h[pn][sn] == 1;}};

思路三:在網上看到的優化方法。記錄前乙個*字元的位置,優先進行單字元匹配,當失敗的時候再回來進行通配。

[cpp]view plain

copy

print?

class solution else

if(*p == '*')  

else

if((!*p || *p != *s)  && star_p)  

else

return

false;  

}  //check if later part of p are all '*'

while(*p)  

if(*p++ != '*')  

return

false;  

return

true;  

}  };  

萬用字元的字串匹配演算法

1.簡述 題目描述 str1中可能包含的字元 除了 和 以外的任意字元。str2中可能包含的字元 任意字元。其中,表示匹配任意乙個字元,表示匹配任意字元0或者多次。給出這樣兩個字串,判斷str2是否是str1的子串,如果是輸出第乙個匹配到的子串,如果不是,輸出 不是子串 2.分析 對於 的處理,只要...

含有萬用字元的字串匹配

字串匹配問題,給定兩個字串,求字串2,在字串1中的最先匹配結果。字串2中可以存在 符號,且該符號可以代表任意字元,即字串2中存在萬用字元。e.g.輸入 abcdefghabef,a f 輸出 abcdef include include using namespace std bool match ...

含有萬用字元的字串匹配

字串匹配問題,給定兩個字串。求字串2。在字串1中的最先匹配結果。字串2中能夠存在 符號,且該符號能夠代表隨意字元,即字串2中存在萬用字元。e.g.輸入 abcdefghabef,a f 輸出 abcdef include include using namespace std bool match ...