【LeetCodeから転載】動的プログラミング問題を解く方法2 LeetCode

1.件名号

10-正規表現マッチング(難しいです)

2.メソッド説明

これは、伝達方程式のDPを決定するために、動的プログラミングを使用して[I] [J] =?

3.10トピックやアイデアやコード、その質問

トピック:

サポート「」と「*」正規表現のマッチングでを実装するためにあなたを招待し、あなたの文字列sと法pを与えます。

「」は任意の単一文字一致
『*』マッチがゼロまたはそれ以上の前述の要素のことを
、いわゆるマッチングは、文字列の文字列の全体ではなく一部を覆うようにします。

説明:

sが空であってもよく、小文字のみからAZ。
pは*空であるとAZ、および文字。とから、小文字のみが含まれていてもよいです。
例1:

入力:
S = "AA"
P = "A"
出力:偽
の解釈: ""文字列全体"AA"に一致することはできません。
例2:

入力:
S =「AA」
P =「A *」
出力:真の
説明:「*」マッチ「」は複数の要素は、この要素の前にあること、ゼロまたは上記の代表です。したがって、文字列は「AA」「」回繰り返されるとみなすことができます。
例3:

入力:
S = "AB&"
P = " "
出力:真
の解釈:. "
任意の文字"を表すゼロ個以上のマッチ( '*')( '')。
例4:

入力:
S = "AAB"
P = "C A B"
出力:真の
説明: 'C'が0である場合'*'手段''は一度繰り返され、さらに、ゼロまたはので。だから、文字列「AAB」を一致させることができます。
例5:

入力:
S = "ミシシッピ"
P = "MIS IS P *。"
出力:偽

伝達方程式を解くのアイデア

定義されたDP [i] [j]は、フロントpはiと文字の最初のj個の文字が一致するよ表し
ケース1を、sの場合は[I]P [J]、またはp [J]「」(任意の文字にマッチする 'ので、等しいと考えることができます)

文字列\場所 0 ...
S ... ... A
文字列\場所 0 ... J
P ... ...

この場合に、DP [I] [J] = DP [I - 1] [J - 1]

ケース2:、P [J] == '*'、次のことが起こります
'' !!ときは2-1 S [I] = P [J - - 1]、 およびP [J 1] = (*文字列に先行する文字の一致していません)

文字列\場所 0 ...
S ... ... A
文字列\場所 0 ... J - 1 J
P ... ... B *

「*」マッチがゼロためまたは前述の代表だけ0を表す複数の要素、すなわち

この場合に、DP [I] [J] = DP [I] [J - 2]

2-2 当s[i]P [J - 1]、またはp [J - 1]''、下:

文字列\場所 0 ...
S ... ... A
文字列\場所 0 ... J - 1 J
P ... ... A *

ここではいくつかの状況を分割:
2-2-1、以下の写真は、S [i]とのp - [J 2]の前に文字列マッチング、*試合0

文字列\場所 0 ... I - 1
S ... ... A B
文字列\場所 0 ... J-3 J - 2 J-1 J
P ... ... A B B *

及びp - 2-2-2下の画像は、[1 i]は - S [J 2]の前に文字列マッチング、*マッチ1

文字列\場所 0 ... I - 1
S ... ... A B
文字列\場所 0 ... J - 2 J-1 J
P ... ... A B *

2-2-3以下の画像はS場合[I - 1]と前回の文字列照合のp [j]は、一致回*

文字列\場所 0 ... I-2 I - 1
S ... ... A B B
文字列\場所 0 ... J - 2 J-1 J
P ... ... A B *

次のように、または関係の3つのケースが、関係は、
DP [I] [J] DP = [I - 1] [J] || DP [I - 1] [J - 2] || DP [I] [ jは- 2]、
境界値の初期化
1.上記の計算を行う前に、アレイのニーズのすべての値がfalseに初期化される、
2.dpは[0] [0] = trueに、それは0 P 0の文字特定の文字を前方前表し及びs一致
3.に== 0のDP値をIを計算する際、ケースがにすべての試合0 *と一致することも可能です。

文字列\場所
S
文字列\場所 0 1 2 3 4 5
P A * B * C *

コード

bool isMatch(char * s, char * p){
    int i, j, len1, len2;
    len1 = strlen(s);
    len2 = strlen(p);
    bool** dp;
    dp = (bool**)malloc(sizeof(bool*) * (len1 + 1));
    for (i = 0; i < len1 + 1; i++) {
        dp[i] = (bool*)malloc(sizeof(bool) * (len2 + 1));
        memset(dp[i], 0, sizeof(bool) * (len2 + 1));
    }
    dp[0][0] = true;
    for (i = 0; i < len2; i++) {
        if (p[i] == '*' && i > 0 && dp[0][i - 1]) {
            dp[0][i + 1] = true;
        }
    }
    for (i = 0; i < len1; i++) {
        for (j = 0; j < len2; j++) {
            if (s[i] == p[j] || p[j] == '.') {
                dp[i + 1][j + 1] = dp[i][j];
                continue;
            }
            if (p[j] == '*' && j > 0) {
                if (s[i] == p[j - 1] || p[j - 1] == '.') {
                    dp[i + 1][j + 1] = dp[i][j + 1] || dp[i][j - 1] || dp[i + 1][j - 1];
                } else {
                    dp[i + 1][j + 1] = dp[i + 1][j - 1];
                }
            }
        }
    }
    return dp[len1][len2];
}

出典:滞在ボタン(LeetCode)
リンクします。https://leetcode-cn.com/problems/regular-expression-matching
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。

リリース元の2件の記事 ウォンの賞賛0 ビュー6

おすすめ

転載: blog.csdn.net/u013947236/article/details/104184616