[LeetCode] 寫一個正則表達式匹配

題目:Regular Expression Matchingexpress

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", "cab") → trueprototype

分析:題目要求挺簡單的,字符匹配,對.*作特殊處理,字符串的匹配能夠拆分紅子串的匹配,子串的匹配又可概括爲每一個字符的匹配,所以這道題用遞歸比較方便。code

首先,拋開.*無論,如何遞歸地判斷兩個字符串相等呢?遞歸

public class Solution {
    public boolean isMatch(String s, String p) {
        int slen = s.length();
        int plen = p.length();

        if (slen == 0 && plen == 0) return true;

        char c0 = getChar(s, 0);
        char p0 = getChar(p, 0);

        if (match(c0, p0)) {
            return isMatch(s.substring(1), p.substring(1));
        }
        return false;
    }

    //判斷兩個字符是否相等
    private boolean match(char a, char b) {
        return a == b;
    }

    //爲何要這個函數呢,主要是爲了統一處理下標越界的問題
    //若是越界了,直接返回0便可
    private char getChar(String s, int p) {
        if (s.length() > p) {
            return s.charAt(p);
        }
        return 0;
    }
}

根據題意,.可根任何字符匹配,那麼match方法就要改爲:element

//判斷兩個字符是否相等
private boolean match(char a, char b) {
    return a == b || b == '.';
}

因爲*對前一個字符有反作用,故須要對*進行特殊判斷。尤爲是[任意字符]*能夠匹配任意長度的字符串,包括空串。所以,每次處理isMatch時,都要向後探一下接下來是否有*字符串

  • 若是有*,則枚舉其匹配全部可能性,只要有一個返回true,則返回true
  • 若是沒有*, 上述代碼的邏輯則不須要變

最終代碼:get

public class Solution {
    public boolean isMatch(String s, String p) {
        int slen = s.length();
        int plen = p.length();

        if (slen == 0 && plen == 0) return true;

        char c0 = getChar(s, 0);
        char p0 = getChar(p, 0), p1 = getChar(p, 1);

        if (match(c0, p0) || p1 == '*') {
            if (p1 != '*') {
                if (slen == 0) return false;
                return isMatch(s.substring(1), p.substring(1));
            }
            // if p1 is *, * means 0 ~ n
            int i = 0;
            boolean ret = isMatch(s.substring(0), p.substring(2)); // try 0
            if (ret) return ret;
            while (i < slen && match(getChar(s, i), p0)) {
                ret = isMatch(s.substring(i+1), p.substring(2)); // try for every available position
                if (ret) return ret;
                i++;
            }
        }

        return false;
    }

    private boolean match(char a, char b) {
        return a == b || b == '.';
    }

    private char getChar(String s, int p) {
        if (s.length() > p) {
            return s.charAt(p);
        }
        return 0;
    }
}
相關文章
相關標籤/搜索