LeetCode10正規表現

調査区間の完成は非常に衝動的となっている、またZuoshaの事、流行がない、家の外に、今では深刻である後、結果の最初の公表も延期と同様の結果を外出する10日、コールは......書き込みアルゴリズムに最初の完全なセットを行います、得点後にして、嘘に行きます。

10個の正規表現

トピックリンク

この問題を試みる前に提出したが、前に、今日アップしませんでした。

問題を解決するには、2つの方法は、動的なプログラミングをバックトラック、報告があります。バックトラックを使用して独自の時間を書くが、そのコードは単純ではなく、包括的とはみなされません。問題解決のための報告書は、コードが本当に爽やかされるバックトラッキングました。

バックトラッキング

このタイトルの兆候がない場合*文字の前に、非常にシンプルになります0回以上*記号は任意の文字と一致する追加。表記を表します。

シンボルとして* 2つのケースがあります。

  • 直前の文字がゼロにマッチします
  • 直前の文字を複数回マッチします

そのため、部分的な状況:( i、j)は、p個の文字列をSの位置を示します

  1. p[j+1] != '*' p[i] == s[i] || p[j] == '.'
    であるS [i]はP [j]が一致し、そしてp [j]は*文字の後ろにされていないこと:オーダーS [I + 1]と文字列の後ろに一致するようにP [J + 1]
  2. p[j+1] == '*'
    我々は2つの状況です。この時、
    マッチ0とき:S [i]とP [J 2 +]文字列の後に、マッチングが成功した場合と比較する
    S [i]を==:マッチングを複数回P [J]と文字列s [I + 1]とp [j]は、正常一致した後に
コード:
	public boolean isMatch(String s, String p) {
        if (p.isEmpty()) return s.isEmpty(); //两者为“” 则为true

		// 第一个字符是否匹配
        boolean first = (!s.isEmpty()) && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.');

        if (p.length() >= 2 && p.charAt(1) == '*') {//有*的时候
            // || 前面为匹配0次的情况 “aab, a*c*b” 
            // || 后面为匹配多次的情况 “aaab, a*b”
            return (isMatch(s, p.substring(2))) || (first && isMatch(s.substring(1), p));
        } else {
            return first && isMatch(s.substring(1), p.substring(1));
        }
    }

ダイナミックプログラミング

ことでdp[i][j]、私はj番目のキャラクタPの成功の前に一致させることができるの前の文字かどうかを示します。
よるとdp[i-1][j-1]裁判官にdp[i][j]

  1. p[j] != '*'
    p[j] == s[i] || p[j] == '.'p[i][j] = p[i-1][j-1]
  2. p[j] == '*'
    p[j-1] != s[i]s[i]そして、*見に必要であるマッチ0、*に一致していませんが、それは試合が失敗したことを意味するものではありません、文字の前があるかもしれない文字の前にdp[i][j-2]:状況dp[i][j] = dp[i][j-2]
    p[j-1] == s[i]と:*前一致する文字が、これは、sの代表ではありません私は、その場合、又は2つの場合に、文字Pに一致する最初のj個の文字の前であってもよい:一致0、すなわち、dp[i][j-2]ケースと、複数のマッチング、即ち、dp[i-1][j]即ちA両方の場合成功があり、成功した。ケース
コード:
    public boolean isMatch(String s, String p) {
        boolean[][] dp = new boolean[s.length()+1][p.length()+1];
        dp[0][0] = true;
        // 相当于初始 "" 被p匹配的情况
        for (int i = 0; i < p.length(); i++) { 
            if (p.charAt(i)=='*' && dp[0][i-1]) dp[0][i+1] = true;
        }
		
        for (int i = 0; i < s.length(); i++) {
            for (int j = 0; j < p.length(); j++) {
                //  s[i] 可以和 p[j] 匹配的情况,看dp前面
                if (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'){
                    dp[i+1][j+1] = dp[i][j];
                }
                if (p.charAt(j) == '*'){
                	// s[i] 和 p[j] 前的字符匹配不上 考虑匹配0次的情况
                    if (p.charAt(j-1) != s.charAt(i) && p.charAt(j-1) != '.'){
                        dp[i+1][j+1] = dp[i+1][j-1];
                    }else{
                    //s[i] 和 p[j] 前的字符匹配上 需要考虑匹配0次和匹配多次的情况 
                        dp[i+1][j+1] = dp[i+1][j-1] || dp[i][j+1];
                    }
                }
            }
        }

        return dp[s.length()][p.length()];
    }
代码中的dp[i][j] 和 s[i] p[j] 中的i和j分别代表各自在各种中的索引
发布了151 篇原创文章 · 获赞 43 · 访问量 10万+

おすすめ

転載: blog.csdn.net/qq_38595487/article/details/104254718