【LeetCode】44.Wildcard Matching解法及び注釈


44. Wildcard Matching
Implement wildcard pattern matching with support for '?' and '*'. 1. '?' Matches any single character. 2. '*' Matches any sequence of characters (including the empty sequence). 3. The matching should cover the entire input string (not partial). 4. The function prototype should be: bool isMatch(const char *s, const char *p) 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
【分析】
この問題は、2つの文字列を指定して一致するかどうかを判断する「ワイルドカード」マッチング問題です.文字列sはワイルドカードを含まない普通の文字列であり、文字列pはワイルドカード「*」と「?の文字列は、文字列pがsと一致するかどうかを判断する必要があります.そのため、2つの文字列の文字を逐次比較する必要があります.
テーマから与えられたexamplesに基づいて,いくつかの基本規則を導くことができる:(ps,ppを文字列sとpの下付きとする)
1.s[ps]==p[pp]の場合、下付き(pp++;ps++)を直接移動し、次の位置の文字が等しいかどうかを比較する.
2.p[pp]='?',では、対応するs[ps]がどんな文字であってもいわゆる、1の処理と同じである.
3.p[pp]=「*」の場合、本題の難点が来た.「*」は任意の文字と文字列に一致することができるが、それがsの中のどの文字と一致するのか、私たちは後の文字を比較する必要がある.例えば、s=「abcacc」、p=「abc*c」、前の3つの文字はすべて一致している.下の文字を移動すればよい.ps=pp=3、すなわち[ps]=「a」、p[pp]=「*」の場合、私たちは「*」がどの文字に一致するか分からないが、後の比較結果に基づいて決定するしかない.私たちはppを次のビットに移動する:p[4]=「c」、s[3]と一致しない.そのため、「*」はs[3]を一致させる必要がある.s[3]がp[3]で一致していると判断しても、p[3]=「*」がs[3]と一致しているとは確定できない.それは複数の文字に一致するので、「*」の位置を保存する必要がある.私達は引き続きpsを移動して、s[ps]=s[4]='c'で、この時ppは3に戻って、同じく、私達はppを移動して、p[pp]=p[4]='c'で、両者はちょうど一致して、同時にppを移動して、ps、sを発見します[5]!=p[5],この場合,我々は「遡及法」の考え方を用いて,ppを再び「*」の位置3に移動し,psを前回すでに「*」で一致したps=3の位置の次の位置に遡り,pp=3の「*」でps=4の位置の文字を引き続き一致させ,psを移動する必要がある.s[ps]=s[5]とp[pp]=p[3]を比較し、p[3]='*'、ppを移動し、次のビットを比較すると、p[4]=s[5]が発見され、同時にpp、psを移動し、文字列sの末尾に達し、サイクル比較が終了する.
4.ループ比較が終了した後、s=「abcacc」、p=「abc*cd」などのpとsのマッチングを決定することはできません.pは同時に文字列の末尾に到達するか、pの後ろに残っている文字がすべて'*'*':s=「abcacc」、p=「abc********」であってこそ、マッチングを形成することができます.
【アルゴリズムおよびコメント】
class Solution {
public:
   bool isMatch(string s,string p)
	{
		int LS,LP;//         ,         
		LS=s.length();
		LP=p.length();

		if(LS==0&&LP==0)return true;//    ,  true
		else if(LS==0&&LP!=0)//s  ,p    '*'   ,  true,    false
		{
			int i=0;
			while(p[i]=='*')i++;
			if(i==LP)return true;//  p       '*'
			else return false;
		}
		else
		{
			int pp,ps;//          
			pp=ps=0;//   
			int matchIndex=0;//          
			int starIndex=0;//     '*'     
			bool flag=false;//         '*'
			while(ps<LS)//      ,      p   s,     s   ,p     s
			{
				if(s[ps]==p[pp]||p[pp]=='?')//      ,      ,     
				{
					pp++;
					ps++;
				}
				else if(p[pp]=='*')//  '*'
				{
					flag=true;//  '*'  
					starIndex=pp;//  ‘*’       
					matchIndex=ps;//     S        
					pp++;//     pp,  s      ,       '*'    
				}
				else
				{
					if(!flag)return false;//           ,        '*',       ,  
					pp=starIndex;//      '*', pp“  ” '*'     
					ps=matchIndex;//ps“  ”             ,    
					ps++;//    s       ,  ps      ,    
				}
			}
			while(p[pp]=='*'&&pp<LP)pp++;// s          ,  p          ,          '*'
			if(p[pp]=='\0')return true;
			else return false;
					
		}	
	}
};