• Leet Code 10.正则表达式匹配


    给你一个字符串s和一个字符规律p,请你来实现一个支持 '.'和 '*'的正则表达式匹配

    解决这个问题有两种方法:回溯和动态规划

    回溯

    字符串为s,正则表达式为p。

    流程如下:

    • 当p为NULL,s为NULL匹配成功,s不为NULL匹配失败。
    • s不为NULL,匹配s和p的第一个字符,注意 '.'。
    • 判断p下一个字符是否为 '*',也要判断p长度是否大于2,否则会报读取索引错误。
    • 若是,匹配s和p.substring(2)或s.substring(1)&&first_match,这样才能回溯所有可能性。
    • 若不是,如果第一个字符相同则匹配s.substring(1)和p.substring(1)。
    • 不相同返回false。
    import java.util.*;
    
    public class leetcode {
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            String s = scan.nextLine();
            String p = scan.nextLine();
            boolean match = isMatch(s,p);
            System.out.println(match);
        }
    
        public static boolean isMatch(String s, String p) {
            if(p.isEmpty() && s.isEmpty()) return true;
            if(p.isEmpty() && !s.isEmpty()) return false;
            //匹配第一个字符
            boolean first_match = !s.isEmpty() && ((s.charAt(0) == p.charAt(0)) || p.charAt(0) =='.');
    
            //判断p第二个字符是否为*
            if(p.length() >= 2 && p.charAt(1)=='*' ) {
                return isMatch(s,p.substring(2)) || first_match && isMatch(s.substring(1),p);
            }
            else {
                if(first_match==true){
                    return isMatch(s.substring(1),p.substring(1));
                }
                else
                    return false;
            }
        }
    }
    

    动态规划

    动态规划分为自顶向下和自底向上两种形式。

    这次采用自顶向下。其中dp[i][j]表示s前i个字符和p前j个字符能够匹配。

    规则归纳:

    1. 如果s[i]==p[j],则dp[i][j]=dp[i-1][j-1]
    2. 如果p[j]=='.',则dp[i][j]=dp[i-1][j-1]
    3. 如果p[j]=='*',则分两种情况:
    4. 第一种情况是p[j-1]!=s[i],那么要去掉这个字符,dp[i][j]=dp[i][j-2]
    5. 第二种情况是p[j-1]==s[i]或者p[j-1]=='.',那么可以一直匹配,这时的匹配情况又有三种。
    dp[i][j]=dp[i-1][j]//匹配多个字符
    dp[i][j]=dp[i][j-1]//匹配单个字符
    dp[i][j]=dp[i][j-2]//匹配0个字符
    三种情况,满足一种即可
    

    初始化规则:

    初始化第一行dp[0][j]
    首先dp[0][0]=true,dp[0][1]=false
    if(p[j-1]=='*') dp[0][j]=dp[0][j-2]
    
    代码
    import java.util.*;
    
    public class leetcode {
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            String s = scan.nextLine();
            String p = scan.nextLine();
            boolean match = isMatch(s,p);
            System.out.println(match);
        }
    
        public static boolean isMatch(String s, String p) {
            //p为null,s不为null则返回false,s为null返回true
            if(p.isEmpty()) return s.isEmpty();
    
            boolean[][] dp = new boolean[s.length()+1][p.length()+1];
            dp[0][0]=true;
            dp[0][1]=false;
            //初始化dp[0][0:p.length()]
            for(int j=2; j<p.length()+1 ;j++) {
                if(p.charAt(j-1)=='*')
                    dp[0][j] = dp[0][j-2];
            }
            //遍历整个dp[][]完成动态规划过程
            for(int i=0; i<s.length(); i++) {
                for(int j=0; j<p.length(); j++) {
                    //p[j]是否为*
                    if(p.charAt(j)=='*') {
                        //两种情况,p[j-1]与s[i]是否相等
                        if(s.charAt(i)==p.charAt(j-1) || p.charAt(j-1)=='.') {
                            //相等的话有三种情况
                            dp[i+1][j+1]=dp[i][j+1] || dp[i+1][j] || dp[i+1][j-1] ;
                        }
                        else {
                            //p[j-1]!=s[i],需要去掉p[j-1]和p[j]
                            dp[i+1][j+1] = dp[i+1][j-1];
                        }
                    }
                    else {
                        //p[j]不为*
                        if(s.charAt(i)==p.charAt(j) || p.charAt(j)=='.') {
                            dp[i+1][j+1]=dp[i][j];
                        }
                        else {
                            dp[i+1][j+1]=false;
                        }
                    }
    
                }
            }
            return dp[s.length()][p.length()];
        }
    }
    

    小结

    最后的动态规划解法,看似简单,但是琢磨了一天。

  • 相关阅读:
    2021广东省强网杯WriteUp
    2021 数字四川创新大赛WriteUp
    2021 陇剑杯wp
    2021 羊城杯WriteUP
    如何翻安全四大顶会的文章
    2021 祥云杯 wp
    codeql初探
    sqlmap应用
    sql注入2
    sql注入
  • 原文地址:https://www.cnblogs.com/chenshaowei/p/12609062.html
Copyright © 2020-2023  润新知