leetcode 10. Regular Expression Matching

本文介绍了一种解决LeetCode 10题——正则表达式匹配问题的动态规划算法。该算法通过构建二维状态表T[i+1][j+1]来表示字符串text[0...i]与模式pattern[0...j]之间的匹配状态。文中详细解释了当模式中包含'*'和'.'等特殊字符时的状态转移方程,并通过实例演示了整个匹配过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode 10. Regular Expression Matching

只有两种特殊字符*和.

  • 动态规划DP
  • empty text与empty pattern是match的
  • 用状态表T[i + 1][j + 1]来表示text[0...i]与pattern[0...j]的匹配状态
    • 当pattern[j]是普通字符或’.’的时候可以归为一种简单的情况
      • 这时候如果text[i] == patter[j] 或 pattern[j] == ‘.’,那么text[0...i]与pattern[0...j]的匹配状态取决于text[0...i-1]与pattern[0...j-1]的状态,即T[i + 1][j + 1] = T[i][j] 
    • 当pattern[j]是字符’*’的时候可以归为另外一种情况
      • 这时候text[0...i]与pattern[0...j]的匹配状态可以取决于两种子串的匹配的状态,一种子串是字符pattern[j-1]还没有出现,另一种子串是字符pattern[j-1]还已经出现。第一种子情况T[i + 1][j + 1]直接取决于T[i + 1][j - 1]。另一种子情况text[0...i]与pattern[0...j]是匹配的当且仅当text[0...i-1]与pattern[0...j]是匹配的,而且text[i] == pattern[j] 或者pattern[j] == ‘.’。
    • 特殊情况。空串与其他不为空的pattern,只有一种递归关系,T[0][j + 1] = T[0][j - 1]
  • 归纳公式
    • T[i][j] = T[i - 1][j - 1]                                             if text[i] == pattern[j] || pattern[j] == ‘.’
    • T[i][j] = T[i][j - 2]     0 occurrence                                                        if pattern[j] == ‘*’
    • T[i][j] = T[i - 1][j]     if text[i] = pattern[j - 1] || pattern[j - 1] == ‘.’          if pattern[j] == ‘*’
    • T[i][j] = false                                                                                          else
  • Example
  •  text: "xaabyc" pattern: "xa*b.c"


  • 0

    1

    2

    3

    4

    5

    6




    x

    a

    *

    b

    .

    c

    0


    T

    F

    F

    F

    F

    F

    F

    1

    x

    F

    T

    F

    T

    F

    F

    F

    2

    a

    F

    F

    T

    T

    F

    F

    F

    3

    a

    F

    F

    F

    T

    F

    F

    F

    4

    b

    F

    F

    F

    F

    T

    F

    F

    5

    y

    F

    F

    F

    F

    F

    T

    F

    6

    c

    F

    F

    F

    F

    F

    F

    T


  • class Solution {
    public:
        bool isMatch(string s, string p) {
            const int rowNum = int(s.length()) + 1;
            const int colNum = int(p.length()) + 1;
            bool table[rowNum][colNum];
            table[0][0] = true;
            for (int i = 1; i < rowNum; i++) {
                table[i][0] = false;
            }
            for (int i = 1; i < colNum; i++) {
                table[0][i] = p[i - 1] == '*'?table[0][i - 2]:false;
            }
            for (int i = 1; i < rowNum; i++) {
                for (int j = 1; j < colNum; j++) {
                    if (s[i - 1] == p[j - 1] || p[j - 1] == '.') {
                        table[i][j] = table[i - 1][j - 1];
                    } else if (p[j - 1] == '*') {
                        bool flag1 = table[i][j - 2], flag2 = false;
                        if (s[i - 1] == p[j - 2] || p[j - 2] == '.') {
                            flag2 = table[i - 1][j];
                        }
                        table[i][j] = flag1 || flag2;
                    } else {
                        table[i][j] = false;
                    }
                }
            }
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    cout << table[i][j] << " ";
                }
                cout << endl;
            }
            return table[rowNum - 1][colNum - 1];
        }
    };


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值