首页 > 试题广场 >

正则表达式匹配

[编程题]正则表达式匹配
  • 热度指数:398613 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
示例1

输入

"aaa","a*a"

输出

true
public class Solution {
    public boolean match(char[] str, char[] pattern) {
        // 记忆化搜索
        cache = new int[str.length + 1][pattern.length + 1];
        return check(str, 0, pattern, 0);
    }
    
    private int[][] cache; // 记忆化搜索存储匹配结果
    private boolean check(char[] str, int x, char[] pattern, int y) {
        if (cache[x][y] != 0) return cache[x][y] == 1;
        if (pattern.length == y) { // 模式串用完
            cache[x][y] = str.length == x ? 1 : -1;
            return str.length == x;
        }
        boolean allMatch; // 全部匹配
        boolean firstMatch = x < str.length && (pattern[y] == '.' || str[x] == pattern[y]); // 首字符匹配
        if (y + 1 < pattern.length && pattern[y + 1] == '*') {
            if (firstMatch) allMatch = check(str, x, pattern, y + 2) || check(str, x + 1, pattern, y);
            else allMatch = check(str, x, pattern, y + 2);
        } else {
            allMatch = firstMatch && check(str, x + 1, pattern, y + 1);
        }
        cache[x][y] = allMatch ? 1 : -1;
        return allMatch;
    }
}

发表于 2021-02-16 20:27:18 回复(0)

思路

动态规划思想。
eg:"abc","ab*.c"。
本质上是利用动态规划思想从后往前遍历。
如:i=2,j=4时,"c"和"c",true;
i=1,j=3时,"b"和"."匹配,则其结果与i+1,j+1时相同(true)。

代码

    public boolean match(char[] str, char[] pattern) {
        // pattern违背规则
        if (pattern.length != 0 && pattern[0] == '*') return false;
        int i = str.length - 1, j = pattern.length - 1;
        while (i >= 0 || j >= 0) {
            // 字符匹配和pattern为'.'的情况
            if (i >= 0 && j >= 0 && (str[i] == pattern[j] || pattern[j] == '.')) {
                i--;
                j--;
                // pattern为'*'的情况
            } else if (j - 1 >= 0 && pattern[j] == '*') {
                return matchHelper(str, i + 1, pattern, j + 1);
            } else {
                return false;
            }
        }
        return i == -1 && j == -1;
    }

    /**
     * 动态规划计算遇到".w"后的匹配情况
     *
     * @param str     原字符集
     * @param sIndex  从后往前起始位置
     * @param pattern 匹配规则字符集
     * @param pIndex  起始位置
     * @return 是否匹配
     */
    private boolean matchHelper(char[] str, int sIndex, char[] pattern, int pIndex) {
        boolean[][] dp = new boolean[sIndex + 1][pIndex + 1];
        // 从后往前,str='',pattern=''时的情况
        dp[sIndex][pIndex] = true;
        //以下举例str:[abc]和pattern:[abc*]
        for (int i = sIndex; i >= 0; i--) {
            for (int j = pIndex - 1; j >= 0; j--) {
                // 下一位是'*'
                if (j < pIndex - 1 && pattern[j+1] == '*') {
                    // 是否和当前str[i]匹配(eg:i=3即str:'',pattern读到:c*)
                    // 匹配,eg: i=2,j=2,即:
                    // "c"和"c*"匹配结果由"c"和"" || ""和"c*"决定。
                    // 也就是说,碰到*且前面char匹配时,要么跳过"c*"(即*代表0个c),
                    // 要么str继续向后读1位(eg:abccc,abc*),意为*多代表了1个c。
                    if (i != sIndex && (str[i] == pattern[j] || pattern[j] == '.')) {
                        dp[i][j] = dp[i+1][j] || dp[i][j+2];
                    } else
                        //若不匹配,则只能跳过“c*",此时*代表0个c
                        dp[i][j] = dp[i][j+2];
                    // 若str[i]与pattern[j]匹配,则结果由二者都向后一位后的结果而定
                    // eg: i=0,j=0 此时[abc]和[abc*],
                    // 其结果等于i=1,j=1时的结果,即[bc]和[bc*]
                } else if (i != sIndex && (pattern[j] == str[i] || pattern[j] == '.')) {
                    dp[i][j] = dp[i+1][j+1];
                }
            }
        }
        return dp[0][0];
    }
发表于 2021-02-01 10:40:33 回复(0)
public class Solution {
    /*
        非递归、非动态规划解法,
        i、j分别指向字符串与正则表达式第一个字符,索引index指向字符串中已被匹配掉字符的后一位
        当i小于字符串长度并且j小于正则表达式长度时:
            若两字符相等,i、j各自向后移动一位,索引index加一
            若两字符不等但正则表达式为“.”时,若“.”后面不是“*”,则i、j各自向后移动一位,且索引index加一;若后面是“*”,则i往后移动一位,j不动,索引index不动
            若两字符不等且正则表达式后面一位是“*”,则i不动,j向后移动两位
            若两字符不等且正则表达式后面一位不是“*”,则返回false
        若i和j都指向最后一位,返回true
        若i没到最后一位,返回false
        若j没到最后一位,分析正则表达式余下的部分:
            若j后一位是“*”,则j向后移动两位,继续循环判断
            若j后一位不再是“*”,则从正则表达式最后一位开始和字符串最后一位比较,若相等则同时往前移动一位继续比较,直至到达j或者索引index的位置,一旦有不一样的就返回false
        上述逻辑若都走完,返回true
    */ 
    public boolean match(char[] str, char[] pattern)
    {
        int i = 0;
        int j = 0;
        int indexStr = 0;
        boolean star = false;
        boolean dot = false;
        while (i < str.length && j < pattern.length) {
            dot = pattern[j] == '.' ? true : false;
            star = j < pattern.length - 1 && pattern[j + 1] == '*' ? true : false;
            if (str[i] == pattern[j] || (dot && !star)) {
                i++;
                if (!star) {
                    j++;
                    indexStr++;
                }
            } else if (star) {
                if (!dot) {
                    j += 2;
                } else {
                    i++;
                }
            } else {
                return false;
            }
        }
        if (i == str.length && j == pattern.length) {
            return true;
        } else if (i < str.length) {
            return false;
        } else if (j < pattern.length) {
            int k = 0;
            for (k = j; k < pattern.length; k++) {
                if (k < pattern.length - 1 && pattern[k + 1] == '*') {
                    k++;
                    continue;
                } else {
                    break;
                }
            }
            int n = str.length - 1 - indexStr;
            for (int m = pattern.length - 1; m >= k; m--) {
                if (n < 0) {
                    return false;
                }
                if (pattern[m] == str[n]) {
                    n--;
                    continue;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
}

发表于 2020-10-30 10:04:14 回复(0)
    /**
     * 回溯递归进行匹配
     * @param str
     * @param pattern
     * @return
     */
    public boolean match(char[] str, char[] pattern){
        int len_s = str.length, len_p = pattern.length;
        // 判断 str 是否为空的字符数组 
        if (len_s == 0) {
            while (len_p - 2 >= 0 && pattern[len_p - 1] == '*') {
                len_p -= 2;
            }
            if (len_p == 0) {
                return true;
            }else {
                return false;
            }
        }
        // 判断 pattern 字符数组是否为空
        if (len_p == 0) {
            if (len_s == 0) {
                return true;
            }else {
                return false;
            }
        }
        // 开始进行 逻辑判断
        if (len_p == 1 || len_p > 1 && pattern[1] != '*') {
            //if the next character in pattern is not '*'
            if (str[0] == pattern[0] || (len_s > 0 && pattern[0] == '.')) {
                return match(String.valueOf(str).substring(1).toCharArray(), String.valueOf(pattern).substring(1).toCharArray());
            }else {
                return false;
            }
        }else {
            //if the next character is '*'
            if (str[0] == pattern[0] || (len_s > 0 && pattern[0] == '.')) {
                //
                return match(str, String.valueOf(pattern).substring(2).toCharArray())
                        || match(String.valueOf(str).substring(1).toCharArray(), pattern);
            }else {
                return match(str, String.valueOf(pattern).substring(2).toCharArray());
            }
        }
    }

发表于 2020-10-02 19:53:01 回复(0)
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        Pattern p=Pattern.compile(new String(pattern));
        Matcher m = p.matcher(new String(str));
        return m.matches();

    }
}

发表于 2020-07-29 09:49:20 回复(0)
没用递归,但需要考虑很多情况,蛮复杂
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        int size=str.length;
        int p_size=pattern.length;
        
        int p1=0;
        int p2=0;
        
        if(p_size==2&&pattern[0]=='.'&&pattern[1]=='*')
            return true;
        
        while(p1<size&&p2<p_size)
        {
            //下一个字符为‘*’
            if(p2+1<p_size&&pattern[p2+1]=='*')
            {
                if(str[p1]==pattern[p2]||pattern[p2]=='.')
                {
                    //计算str该字符有多少个
                    int n1=p1+1;
                    while(n1<size&&str[p1]==str[n1])
                    { 
                        n1++;
                    }
                    int count1=n1-p1;
                       
                    //计算pattern该字符有多少个
                    int n2=p2+2;
                    while(n2<p_size&&pattern[n2]==pattern[p2])
                    {
                        n2++;
                    }
                    int count2=n2-p2;
                    
                    //是否满足匹配条件
                    if(count2-2<=count1)
                    {
                        p1=n1;
                        p2=n2;
                        continue;
                    }
                    else
                        return false;
                }
                else
                {
                    p2=p2+2;
                    continue;
                }
            }
            //下一个字符不为‘*’,直接比较
            if(str[p1]==pattern[p2]||pattern[p2]=='.')
            {
                p1++;
                p2++;
                continue;
            }
            else
                return false;
        }
  
        if(p1==size && p2==p_size)
            return true;
        else
        {
            //pattern多出来‘*’或者多出来“x*”
            if(p1==size && pattern[p_size-1]=='*'&&p_size-p2<=2)
                return true;
            
            if(p1==size)
            {
                int n2=p_size-1;
                int n1=size-1;
                
                //aaa和aa*c*a     
                if(n1>=0 && pattern[n2]==str[n1])
                {
                    n2--;
                    n1--;
                    while(n1>0&&n2>p2&&pattern[n2]==str[n1])
                    {
                        n1--;
                        n2--;
                    }
                }
                //aa和aa*c*
                while(n1>=0 && n2-1>=p2 && pattern[n2]=='*')
                {
                    if(pattern[n2-1]!=str[n1])
                    {
                        n2=n2-2;
                    }
                    if(n2-1<p2)
                        return true;
                    if(pattern[n2-1]==str[n1]&&p2==n2-1)
                    {
                        return true;
                    }
                }
                return false;
            }
            else
                return false;
        }
    }
}




发表于 2020-07-23 16:37:44 回复(0)
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        return match(str, 0, pattern, 0);
    }
  
    //回溯法
    private boolean match(char[] str, int i, char[] pattern, int j) {
       if (str.length <= i && pattern.length - j == 2 && pattern[j+1] == '*') {
         // a* 的情况
         return true;
       } 
       if (i >= str.length && j >= pattern.length) {
         return true;
       }
       if (i >= str.length || j >= pattern.length) {
         return false;
       }
       if (j+1 < pattern.length && pattern[j+1] == '*') {
         if (pattern[j] != str[i] && pattern[j] != '.') { //当前2个不相等, pattern跳到*号后一个
            return match(str, i, pattern, j+2);
         } else {
            if(match(str, i+1, pattern, j)) { //str跳下一个和pattern比
              return true;
            } else {
              return match(str, i, pattern, j+2);
            }
         }
       } else if (j+1 == pattern.length || 
                  (j+1 < pattern.length && pattern[j+1] != '*')) { //字符后面不为*的情况
         if (pattern[j] == str[i] || pattern[j] == '.') {
           return match(str, i+1, pattern, j+1); //两指针后移动,再比较
         } else {
           return false;
         }
       }
       return false;      
    }
}

发表于 2020-06-14 18:30:42 回复(0)
动态规划,LeetCode10,hard。
public class Solution {
    public boolean match(char[] str, char[] pattern){
        int m = str.length;
        int n = pattern.length;
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int i = 1; i <= n; i++) {
            if (pattern[i - 1] == '*') dp[0][i] = dp[0][i - 2];
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (pattern[j - 1] == str[i - 1] || pattern[j - 1] == '.') {
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (pattern[j - 1] == '*') {
                    if (pattern[j - 2] == str[i - 1] || pattern[j - 2] == '.') {
                        dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
                    } else dp[i][j] = dp[i][j - 2];
                }
            }
        }
        return dp[m][n];
    }
}

发表于 2020-05-27 21:47:24 回复(0)
自己琢磨了一会儿 没有整出来,最后参考别人的才勉勉强强;
主要是判断条件的设定以及顺序,用的是递归的方式依次判断;
public class Solution {
    public boolean matchstr(char[] A,int i,char[] B,int j){
        //边界    判断  
        if(i==A.length && j==B.length){
             return true;
        }else if(j==B.length) {
            return false;
        }//
        boolean next =(j+1<B.length && B[j+1]=='*');// 模式串下一个字符是'*'
        if(next){
            if(i<A.length && (B[j]=='.' || A[i]==B[j])){
                return matchstr(A, i, B, j+2) || matchstr(A,i+1,B,j);
            }else {
                return matchstr(A, i, B, j+2);
            }
        }else{
            if(i<A.length && (B[j]=='.' || A[i]==B[j])){
                return matchstr(A, i+1, B, j+1);
            }else {
                return false;
            }
        }
    }
    
    public boolean match(char[] str, char[] pattern)
    {
        return matchstr(str,0,pattern,0);
    }
}


发表于 2020-04-21 13:48:54 回复(0)
循环写法虽然代码量长,但是挺简单的,从后往前比较
public class Solution{
    public static boolean match1(char[] str, char[] pattern){
        int len1 = str.length-1;
        int len2 = pattern.length-1;
        //如果str为空数组,则只在pattern为空或者len2==1&&pattern[1]=='*'时返回true
        if(len1==-1){
            if(len2==-1){
                return true;
            }
            if(len2==1&&pattern[1]=='*'){
                return true;
            }
            return false;
        }
        //字符串和模式都不为空
        while(len1>=0 && len2>=0){
            if(pattern[len2]=='*'){
                --len2;
                while(str[len1]==pattern[len2]||pattern[len2]=='.'){
                    --len1;
                    if(len1<0){
                        return true;
                    }
                }
                --len2;
            }
            if(str[len1]==pattern[len2]||pattern[len2]=='.'){
                --len1;
                --len2;
            }
            else if(pattern[len2]=='*'){
                continue;
            }
            else{
                return false;
            }
        }
        if(len1==-1&&len2==-1){
            return true;
        }
        return false;
    }
}


编辑于 2020-04-18 16:59:36 回复(0)
使用dfs,逻辑过程见注释,应该很详细了
//使用dfs
private boolean matchDfs(char[] str,int i,char[] pattern,int j){
    if(i==str.length&&j==pattern.length) return true;//刚好匹配
    if(j==pattern.length) return i==str.length;//pattern已经用完了,这时看str是否用完了
    if(i==str.length){//str用完了
        if(j==pattern.length-1) return false;//如果pattern只剩一个字符了,那是不可能匹配上的
        if(pattern[j+1]=='*') return matchDfs(str,i,pattern,j+2);//pattern的j+1个字符是'*',这是可以使'*'匹配低j个字符0次
    }else{//str没用完
        if(j==pattern.length-1){//如果pattern只剩当前一个字符了(潜台词是后面没有'*')
            if(pattern[j]=='.'||pattern[j]==str[i]) return matchDfs(str,i+1,pattern,j+1);//str的当前字符可以和pattern的当前字符匹配
            else return false;//不能匹配那就返回false了
        }else{//pattern后续还有字符,也就是说可能存在'*' (之前的边界判断都是为了在这里方便的判断'*'是否存在)
            if(pattern[j+1]=='*'){//pattern后面一个字符是'*'
                if(str[i]!=pattern[j]&&pattern[j]!='.') return matchDfs(str,i,pattern,j+2);//str的当前字符和pattern的当前字符不匹配,这时可以使'*'匹配0次
                else return matchDfs(str,i,pattern,j+2)||matchDfs(str,i+1,pattern,j);//当前字符匹配,那么可以继续匹配0次或大于等于1次
            }else{//后面一个字符不是'*'
                if(str[i]!=pattern[j]&&pattern[j]!='.') return false;//当前字符不匹配,返回false
                else return matchDfs(str,i+1,pattern,j+1);//当前字符匹配,那么继续匹配下一个
            }
        }
    }
    return false;
}
public boolean match(char[] str, char[] pattern) {
    if(str==null&&pattern==null) return true;
    if(str==null||pattern==null) return false;
    if(pattern.length==0) return str.length==0;
    return matchDfs(str,0,pattern,0);
}

更简单的就是使用正则表达式了,见下面:
//tip: 使用正则表达式
public boolean match(char[] str, char[] pattern) {
    Pattern p=Pattern.compile(String.valueOf(pattern));
    Matcher m=p.matcher(String.valueOf(str));
    if(m.find()){
        if(m.group().equals(String.valueOf(str))) return true;
    }
    return false;
}



发表于 2020-03-14 21:31:21 回复(0)
    public boolean match(char[] str, char[] pattern) {
        if (str.length == 0 && pattern.length == 0) {
            return true;
        }
        return matchCore(str, pattern, 0, 0);
    }

    public boolean matchCore(char[] str, char[] pattern, int strIndex, int patIndex) {
        if (strIndex == str.length && patIndex == pattern.length) {
            return true;
        }
        if (strIndex != str.length && patIndex == pattern.length) {
            return false;
        }
        // 下一个是*
        if (patIndex + 1 < pattern.length && pattern[patIndex + 1] == '*') {
            if (strIndex == str.length || str[strIndex] != pattern[patIndex] && pattern[patIndex] != '.') {
                return matchCore(str, pattern, strIndex, patIndex + 2); // 当前不匹配,只能跳过
            } else {
                return matchCore(str, pattern, strIndex + 1, patIndex)
                        || matchCore(str, pattern, strIndex, patIndex + 2); // 当前匹配,可选择是否跳过
            }
        }
        // 下一个不是*
        if (strIndex < str.length && (str[strIndex] == pattern[patIndex] || pattern[patIndex] == '.')) {
            return matchCore(str, pattern, strIndex + 1, patIndex + 1);
        } else {
            return false;
        }
    }
看了一遍书本答案后再写就简单多了,思路也比较清晰。。自己的改了半天难看得要死...
发表于 2020-03-05 15:48:51 回复(0)
import java.util.*;
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        String p = new String(pattern);
        String s = new String(str);
        if(s.matches(p)){
            return true;
        }
        return false;
    }
}
这是直接利用了java的库函数,用了个投机取巧的方法。

发表于 2020-02-28 10:21:00 回复(0)
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        String s="",reg="";
        int i;
        for(i=0;i<str.length;i++){
            s=s+str[i];
        }
        for(i=0;i<pattern.length;i++){
            reg=reg+pattern[i];
        }
        return s.matches(reg);
    }
}

发表于 2020-02-26 17:45:39 回复(0)
Java实现,已通过。递归求解。运行时间:24ms,占用内存:9548k。
这道题... ... 好然。主要是理解题意: “匹配” 。 字符串"aaa" 与 模式"a.a"匹配,但是"aaa" 与"aa.a"不匹配,因为遍历 “aa.a” 走到 "." 时,字符串 “aaa” 已经与之匹配完毕,但是模式串还剩个 "a" ,所以匹配失败。因此,与之前遇到的“aaa” 是 “aaaaa” 的子串不同,这道题的模式匹配是:,一定要把模式串遍历完毕的,如果模式串有剩余,那就匹配失败。
(这里的“遍历”是指,将两个数组的字符进行挨个匹配了。对于个体来说是相同字符。)
当模式串遍历完毕时,如果字符串也遍历完毕,OK 匹配成功。
当模式串遍历完毕时,如果字符串还没遍历完,匹配失败。
而如果以字符串遍历完毕与否为标准:当字符串遍历完毕时,如果模式串没有遍历完毕,匹配成功与否是不一定的:比如,字符串 “ab” 与模式串 “ ac*b ”是匹配成功的,而与模式串 "abc "是匹配失败的。
也就是说  匹配成功意味着:字符串 str 遍历到末尾,同时 模式串 pattern 也遍历到末尾; 但是并不意味着模式串 pattern的最后一个字符和 字符串 str 的最后一个字符匹配
方法中传入两个字符数组与分别的下标,进行挨个匹配,返回两个字符匹配结果。
public boolean match(char[] str, int strIndex,char[] pattern,int patIndex)
1.如果 模式串对应的字符 的下一个是 " * ", 而且模式串的当前这个字符可以与字符串的字符匹配,根据模式串的当前这个字符可以匹配到几个字符可能有以下几种配对方式:
比如 模式串是“ ab* c” ,当前遍历到 "b" 了
(1)字符串是 "ac"  ,这时 “*” 匹配到 0 个字符。即 结果是 match(str, srtIndex,pattern,pattern+2),也就是说 “b*” 是没有用的,需要往后跳 2 个,继续去向后遍历、匹配。
(2)字符串是 "abc"  ,这时 “*” 匹配到 1 个字符。即 结果是 match(str, srtIndex+1,pattern,pattern+2) 。
(3)字符串是 "abbbbbc"  ,这时 “*” 匹配到 5 (多个 )个字符。
即 结果是 match(str, srtIndex+1,pattern,pattern),也就是等同于 字符串再继续向后遍历。
以上 3 种情况用 或 || 联系即可。
如果模式串的当前这个字符不能与字符串的字符,要注意 “ * 表示它前面的字符可以出现任意次(包含0次)” 也就是说 “ ab* c” 可以是 "ac" 的,需要给模式串往后跳 2 格,继续匹配。
2.如果 模式串对应的字符 的下一个不是 " * ", (注意,如果到了下标是长度-1 ,也就是 char 数组最后一个,下标+1 是会越界的,正好最后一个了,也不会遇到 “*” 了,所以
(patIndex==patLen-1||pattern[patIndex+1]!='*')
应该放一起。)当匹配串当前字符为 ".",可以匹配任意字符;或者两个字符相同时,结果为两个下标分别+1  去看匹配结果,否则,得返回 false。
再有,1.2 之前都应先判断匹配串历完毕的情况,如果此时字符串未遍历完,匹配失败;
如果此时字符串遍历完,匹配成功。
在1.2 中,对于1 ,还可能出现字符串未遍历完,但是匹配成功的情况,因为 * 可以表示0次数呀,比如 “abcdefg” 与 "“abcdefgh* ",这时返回的结果是 :match(str, srtIndex,pattern,pattern+2) 。
对于2 ,肯定是匹配失败了,眼看着匹配串多出来了,而且还没有 * 表示 0 次数可以让前面的字符消失。
代码如下:
public class Solution {
    //思路:递归求解
    public boolean match(char[] str, char[] pattern)
    {
if(str==null||pattern==null) return false;
        		return match(str,0,pattern,0);}
    public boolean match(char[] str, int strIndex,char[] pattern,int patIndex)
    {
        int strLen=str.length;
        int patLen=pattern.length;
//如果模式串遍历完,而str 也完,应当返回 true
        if(patIndex==patLen&&strIndex==strLen) {
return true;}
//如果模式串遍历完,而str 没完,应当返回 false
        if(patIndex==patLen&&strIndex!=strLen)
        {return false;}


        //接下来都是 模式串没完的情况


if(patIndex==patLen-1||pattern[patIndex+1]!='*')
{
    if(strIndex==strLen) return false;
        if(pattern[patIndex]=='.'||pattern[patIndex]==str[strIndex])
        return match(str,strIndex+1,pattern,patIndex+1);
        else return false;
    else {
    if(strIndex==strLen)
       return match(str,strIndex,pattern,patIndex+2);
    if(pattern[patIndex]=='.'||str[strIndex]==pattern[patIndex])
        return match(str, strIndex + 1, pattern, patIndex + 2) ||
                match(str, strIndex , pattern, patIndex + 2) ||
                match(str, strIndex + 1, pattern, patIndex);

  else return match(str,strIndex,pattern,patIndex+2);
}}}



编辑于 2020-02-14 13:43:00 回复(0)
 * 思路:找出重点关注的地方分情况讨论
 * ∵ .表示任意字符,所以当模式中的某个字符为.或和字符串中的某字符相等时则匹配,进入下一个字符比较
 * 重点考虑*
 * 一般情况:
 * 当第二个字符为*时(第一个字符为*没有意义,划分问题规模),可以选择三种情况
 *
 * 如果str第一个字符与pattern第一个字符相同或者pattern第一个字符为.,此时*和前面的字符匹配
 * 第一种:模式向后移动2个字符,字符串向后移动1个字符,继续匹配(比如aaa和a*a*a)
 * 第二种: 模式不移动,字符串向后移动一位,继续匹配* (比如aaa和a*)
 * 第三种:模式向后移动2个字符,*表示前面字符为0,相当于忽略*和前面的字符,字符串不移动(比如aaa和a*a*a*a)
 *
 * 如果str第一个字符与pattern第一个字符不相同,此时*和前面的字符不匹配
 * 模式向后移动两位,字符串向后移动一位,比较下一位,(比如aaa和b*a*b)
 *
 * ========================
 * 如果第二个字符不为*
 * 当第一个字符一样,可能匹配成功或者失败,进入递归
 * 如果第一个字符不一样,则必定失败(为*可以表示前一个字符出现0次)
 *========================
 * 找出base case(何时才算匹配成功):
 * 当str和pattern都走到尾,表示pattern匹配str成功
 * 当str未走到尾,pattern已经走到尾,此时pattern匹配str失败,str还有剩余字符未匹配
 * 当str走到尾,pattern未走到尾,或str和pattern都未走到尾,此时可能匹配成功,也可能失败,进入一般情况。
 *
 */
 public class Solution {
    public  boolean match(char[] str, char[] pattern) {
        if (str == null || pattern == null) {
            return false;
        }
        return matchCore(0, str, 0, pattern);
    }

    private  boolean matchCore(int strIndex, char[] str, int patternIndex, char[] pattern) {
        if (strIndex == str.length && patternIndex == pattern.length) {
            return true;
        }
        if (strIndex != str.length && patternIndex == pattern.length) {
            return false;
        }
        // 注意保证数组下标不越界
        // 第二个字符为*
        if ((patternIndex + 1) < pattern.length && pattern[patternIndex + 1] == '*') {
            if ((strIndex < str.length && str[strIndex] == pattern[patternIndex]) ||
                    (strIndex < str.length && pattern[patternIndex] == '.')) {
                return matchCore(strIndex, str, patternIndex + 2, pattern)
                        || matchCore(strIndex + 1, str, patternIndex + 2, pattern)
                        || matchCore(strIndex + 1, str, patternIndex, pattern);
            } else { // 第一个字符不匹配
                return matchCore(strIndex, str, patternIndex + 2, pattern);
            }
        }
        if ((strIndex < str.length && pattern[patternIndex] == str[strIndex])
            || (strIndex < str.length && pattern[patternIndex] == '.')) { // 第二个字符不为*,第一个字符匹配
               return matchCore(strIndex + 1, str, patternIndex + 1, pattern);
        }
        return false;
    }
}

发表于 2020-01-07 16:14:34 回复(0)
public class MatchPattern {
    public boolean match(char[] str, char[] pattern)
    {
    	if(str == null || pattern == null)
    		return false;
    	
    	return matchCore(str,0,pattern,0);
        
    }
    
    private boolean matchCore(char[] str,int strIndex,char[] pattern ,int patternIndex){
    	if(strIndex == str.length && patternIndex == pattern.length)
    		return true;
    	if(strIndex < str.length && patternIndex == pattern.length)
    		return false;
    	
    	if(patternIndex + 1< pattern.length  && pattern[patternIndex + 1] == '*'){
    		if((strIndex < str.length && pattern[patternIndex] == '.')
    			||(strIndex < str.length && pattern[patternIndex] == str[strIndex])){
    			return matchCore(str,strIndex,pattern,patternIndex + 2)
    					||matchCore(str,strIndex+1,pattern,patternIndex + 2)
    					||matchCore(str,strIndex+1,pattern,patternIndex);
    		}
    		else{
    			return matchCore(str,strIndex,pattern,patternIndex + 2);
    		}
    	}
    	
    	if((strIndex < str.length && patternIndex < pattern.length &&  str[strIndex] == pattern[patternIndex]) 
    			|| (strIndex < str.length && patternIndex < pattern.length && pattern[patternIndex]== '.')){
    		return matchCore(str,strIndex + 1,pattern,patternIndex + 1);
    	}
    	return false;
    }
}

发表于 2019-12-12 12:44:02 回复(0)
//动态规划解法
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        boolean[][] dp;
        int i, j, ls, lp;

        ls = str.length;
        lp = pattern.length;
        dp = new boolean[lp+1][ls+1];
        dp[0][0] = true;
        for(i = 0; i < lp; i++)
            if(pattern[i] == '*')
                dp[i+1][0] = dp[i-1][0];
        for(i = 0; i < lp; i++){
            for(j = 0; j < ls; j++){
                if(pattern[i] == '*')
                    dp[i+1][j+1] = dp[i-1][j+1] || dp[i][j+1] || (str[j] == pattern[i-1] || pattern[i-1] == '.') && dp[i+1][j];
                else if(pattern[i] == '.' || pattern[i] == str[j])
                    dp[i+1][j+1] = dp[i][j];
                else
                    dp[i+1][j+1] = false;
            }
        }
        return dp[lp][ls];
    }
}

发表于 2019-12-01 10:46:55 回复(0)

public class Solution {
    public boolean match(char[] str, char[] pattern){
        if(str == null || pattern == null) return false;
        if(str.length == 0){
            if(pattern.length == 0 || (pattern.length == 2 && pattern[1] == '*')){
                return true;
            }else{
                return false;
            }
        }
        if(pattern.length == 0)return false;
        int i = 0;
        int j = 0;
        while(i < str.length){
            if(j == pattern.length - 1){
                if(i == str.length - 1 && (str[i] == pattern[j] || pattern[j] == '.')){
                    return true;
                }else{
                    return false;
                }
            }
            if(j > pattern.length - 1) return false;
            if(pattern[j + 1] == '*'){
                int index = i;
                // 记录回退数量,管理这样的"a*a"的匹配
                int back = 0;
                int point = j + 1;
                while(++point <= pattern.length - 1 && ((index + 1 < str.length && str[index + 1] == pattern[j]) || index + 1 == str.length)){
                    if(pattern[point] == pattern[j]){
                        back++;
                        if(point + 1 <= pattern.length - 1 && pattern[point] == '*')back--;
                    }
                }
                // 单独处理"."的回退问题
                while(++point <= pattern.length - 1 && pattern[j] == '.'){
                    back++;
                    if(point + 1 <= pattern.length - 1 && pattern[point] == '*')back--;
                }
                while(index < str.length && (str[index] == pattern[j] || pattern[j] == '.')){
                    index++;
                }
                index-=back;
                if(index == str.length && j + 1 == pattern.length - 1)return true;
                if(j + 1 == pattern.length - 1)return false;
                if(index == str.length)return false;
                j+=2;
                i = index;
            }else{
                if(str[i] != pattern[j] && pattern[j] != '.')return false;
                i++;
                j++;
            }
        }
        if(j + 1 == pattern.length - 1 && pattern[j + 1] == '*')return true;
        return false;
    }
}

发表于 2019-10-20 18:00:36 回复(0)
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        String string = new String(str);
        String regex = new String(pattern);
        return string.matches(regex);
    }
}

   取个巧。。。
发表于 2019-10-08 11:56:31 回复(0)