1. 程式人生 > >萬用字元匹配

萬用字元匹配

給定一個字串 (s) 和一個字元模式 § ,實現一個支援 ‘?’ 和 ‘*’ 的萬用字元匹配。

‘?’ 可以匹配任何單個字元。
‘*’ 可以匹配任意字串(包括空字串)。
兩個字串完全匹配才算匹配成功。

說明:

s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字元 ? 和 *。
示例 1:

輸入:
s = “aa”
p = “a”
輸出: false
解釋: “a” 無法匹配 “aa” 整個字串。
示例 2:

輸入:
s = “aa”
p = ""
輸出: true
解釋: '
’ 可以匹配任意字串。
示例 3:

輸入:
s = “cb”
p = “?a”
輸出: false
解釋: ‘?’ 可以匹配 ‘c’, 但第二個 ‘a’ 無法匹配 ‘b’。
示例 4:

輸入:
s = “adceb”
p = “ab”
輸出: true
解釋: 第一個 ‘’ 可以匹配空字串, 第二個 '’ 可以匹配字串 “dce”.
示例 5:

輸入:
s = “acdcb”
p = “a*c?b”
輸入: false

方法:逐個比較
思路:
1,將字串s和p的字元挨個比較,i和j指標分別記錄位置,如果相同或者p的j位置字元為’?’,則將i和j指標前進一步;
2,如果不滿足第一步條件,但是此時p的j位置字元為 萬用字元’*’,那麼就記錄此時i和j的位置,並且將j前進一步;
3,再將i和前進一步的j重複,第一步的操作,如果還是不匹配,那麼就需要萬用字元的匹配,就將當前i位置的元素直接匹配掉,拿著下一個元素和j位置的元素繼續比較,並且更新記錄中記錄的位置;
4,如果沒有完全匹配,或者匹配過程有錯誤,直接返回false;否則就直到將s字串完全匹配完成;
5,如果已經完全匹配,但是p字串指標j還沒有遍歷完成,那麼就需要此時p剩下的字串全部是萬用字元才算完全匹配,否則就返回false;
6,全部遍歷完成,就說明匹配成功,返回true;

class Solution {
    public boolean isMatch(String s, String p) {
       //動態規劃,逐個匹配
        int sl = s.length();
        int pl = p.length();
        //雙指標移動兩個元素
        int i = 0, j = 0;
        //記錄匹配到'*'的位置,方便操作
        int marks = -1, markp = -1;
        while (i < sl) { 
            if (j != pl && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?')) {//直接字元匹配或者p裡面是'?',直接走
                i ++;
                j ++;
            }
            else if (j != pl && p.charAt(j) == '*') {//是'*'時,記錄當前i和j,並且先把j指標走一步
                marks = i;
                markp = j;
                j ++;
            }
            else if (markp != -1) {//j走一步後和i不匹配,則需要用'*'匹配掉當前i,所有i走一步,j退一步,再繼續比較
                i = marks + 1;
                j = markp + 1;
                marks ++;
            }
            else {//沒有完全匹配或者匹配不正確
                return false;
            }
        }
        while (j < pl) {//s已經完全匹配完,但是j指標還沒有走完的情況
            if (p.charAt(j) == '*') 
                j ++ ;
            else
                return false;
        }
        return true;
    }
}

注意:主要就是萬用字元的匹配,可以匹配空字元,所以每次要先跳過在比較,後續不匹配再返回標記位置使用萬用字元匹配掉當前字元,重複操作直到出現匹配字元為止!