[譯]正規表示式匹配

凌浩雨發表於2017-11-07

原文地址: 正規表示式匹配

實現正規表示式匹配需要支援`.`和`*`.

`.` 匹配任何一個字元.
`*` 匹配0或以上的前一個元素.

匹配應該覆蓋整個輸入字串(不是部分)。
函式原型應該是:
bool isMatch(const char *s, const char *p)

一些例子:

isMatch("aa","a") return false
isMatch("aa","aa") return true
isMatch("aaa","aa") return false
isMatch("aa", "a*") return true
isMatch("aa", ".*") return true
isMatch("ab", ".*") return true
isMatch("aab", "c*a*b") return true
  1. 分析
    首先,這是最困難的問題之一。很難去考慮所有不同的情況。這個問題應該簡化為處理2個基本情況:
    • 第二字元匹配是`*`
    • 第二字元匹配不是`*`
      對於第一種情況, 如果第一個字元的匹配是`.`, 第一個字元匹配和字串應該是相同的,然後繼續匹配剩下的部分.
      對於第二種情況, 如果第一個字元的匹配不是`.`或者第一個匹配字元是恆等於字串中的某個字元,然後繼續匹配剩下的部分.

Java 解決方案 1 (簡單的)

public class Solution {
    public boolean isMatch(String s, String p) {
 
        if(p.length() == 0)
            return s.length() == 0;
 
        //p`s length 1 is special case    
        if(p.length() == 1 || p.charAt(1) != `*`){
            if(s.length() < 1 || (p.charAt(0) != `.` && s.charAt(0) != p.charAt(0)))
                return false;
            return isMatch(s.substring(1), p.substring(1));    
 
        }else{
            int len = s.length();
 
            int i = -1; 
            while(i<len && (i < 0 || p.charAt(0) == `.` || p.charAt(0) == s.charAt(i))){
                if(isMatch(s.substring(i+1), p.substring(2)))
                    return true;
                i++;
            }
            return false;
        } 
    }
}

Java 解決方案 2 (更受歡迎)

public boolean isMatch(String s, String p) {
    // base case
    if (p.length() == 0) {
        return s.length() == 0;
    }
 
    // special case
    if (p.length() == 1) {
 
        // if the length of s is 0, return false
        if (s.length() < 1) {
            return false;
        }
 
        //if the first does not match, return false
        else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != `.`)) {
            return false;
        }
 
        // otherwise, compare the rest of the string of s and p.
        else {
            return isMatch(s.substring(1), p.substring(1));
        }
    }
 
    // case 1: when the second char of p is not `*`
    if (p.charAt(1) != `*`) {
        if (s.length() < 1) {
            return false;
        }
        if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != `.`)) {
            return false;
        } else {
            return isMatch(s.substring(1), p.substring(1));
        }
    }
 
    // case 2: when the second char of p is `*`, complex case.
    else {
        //case 2.1: a char & `*` can stand for 0 element
        if (isMatch(s, p.substring(2))) {
            return true;
        }
 
        //case 2.2: a char & `*` can stand for 1 or more preceding element, 
        //so try every sub string
        int i = 0;
        while (i<s.length() && (s.charAt(i)==p.charAt(0) || p.charAt(0)==`.`)){
            if (isMatch(s.substring(i + 1), p.substring(2))) {
                return true;
            }
            i++;
        }
        return false;
    }
}


相關文章