1. 程式人生 > >leetcode 10: Regular Expression Matching 分析及解答

leetcode 10: Regular Expression Matching 分析及解答



Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

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", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

解讀:

  • ‘.'代表一個任意字元,與其附近的字元無關
  • ’*‘代表o個或者多個前面的字元,該字元影響前面字元的“存在”,例如:a*={ε,a,aa,aaa,…},即當"*"表示0個前面的字元時,該字串為空串ε。

分析:題目要求匹配整個輸入字串,即完全匹配,分如下情況:

  1. 同時為空則true
    p為ε時,s為ε則匹配
    s為ε時,p為ε則匹配,但此時p分兩種情況:
      1、p確實為ε
      2、p為”a*“型別,此時*代表前面的字元存在0次,則p在匹配意義上位ε
  2. 不同時為空就需要比較
  • p字串中當前字元是否匹配與其下一個是否為’*‘有關,所以分兩種情況
    [p+1]=='*' 則 匹配當前字元或者匹配下兩個字元[p+2](即不匹配當前字元,此時*表示當前字元出現零次,即p=ε[p+2])
    [p+1]!='*' 對當前字元進行匹配

請看程式碼:

public class Solution {
    public boolean isMatch(String s, String p) {
       //1、字元同時為空的情況
       //1.1先考慮p為空,此時只要看s是否為空即可。
       if(p.length()==0) return s.length()==0;
       //1.2 再考慮s為空的情況
       else if(s.length()==0)
       {
	       //1.2.1 p分兩種情況
           //if(p.length()==0)return true;//情況1 p確實為空。
           if(p.length()>1&&p.charAt(1)=='*')return isMatch(s,p.substring(2));//情況二,”匹配“意義上為空
           else return false;
       }

       //2、不同時為空則進行匹配
       else 
       {
            //2.1 如果p的下一個字元為’*‘則分兩種情況
       	    if(p.length()>1&&p.charAt(1)=='*')
       	    {
	    		//2.1.1 匹配下兩個字元
           		if(isMatch(s,p.substring(2))) return true;
 		    	//2.1.2 匹配當前字元,注意:此時p字串不步進
           		else if(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.')return isMatch(s.substring(1),p);
           		else return false;
       	    }
            //2.2 匹配當前字元
       	    else
           {
              if(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.')return isMatch(s.substring(1),p.substring(1));
              else return false;
           }
       }
    }
}