Implementação de Correspondência de Expressões Regulares com Programação Dinâmica

Descrição do Problema

Dada uma string s e um padrão p, implemente uma função que verifique correspondência de expressões regulares com suporte a '.' e '*':

  • '.' corresponde a qualquer caractere único
  • '*' corresponde a zero ou mais ocorrências do elemento precedente

A correspondência deve abranger toda a string s, não parcial.

Abordagem de Solução

Utiliza-se programação dinâmica para resolver eficientemente o problema:

Definição de Estado

tabela_dp[i][j] indica se os primeiros i caracteres de s correspondem aos primeiros j caracteres de p.

Inicialização

tabela_dp[0][0] = True (strings vazias correspondem). Para i > 0, tabela_dp[i][0] = False (padrão vazio não corresponde a string não vazia).

Transição de Estado

Para cada par (i, j) onde i varia de 0 a n (comprimento de s) e j de 1 a m (comprimento de p):

  • Se p[j-1] == '*':
    • Verifique correspondência entre s[i-1] e p[j-2]
    • Se corresponderem: tabela_dp[i][j] = tabela_dp[i-1][j] or tabela_dp[i][j-2]
    • Caso contrário: tabela_dp[i][j] = tabela_dp[i][j-2]
  • Se não:
    • Se s[i-1] e p[j-1] corresponderem: tabela_dp[i][j] = tabela_dp[i-1][j-1]
    • Caso contrário: tabela_dp[i][j] = False

O resultado final é tabela_dp[n][m].

Código em Python

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        n, m = len(s), len(p)
        tabela_dp = [[False] * (m + 1) for _ in range(n + 1)]
        tabela_dp[0][0] = True
        
        def verifica_correspondencia(idx_s: int, idx_p: int) -> bool:
            if idx_s < 0 or idx_p < 0:
                return False
            if p[idx_p] == '.':
                return True
            return s[idx_s] == p[idx_p]
        
        for i in range(n + 1):
            for j in range(1, m + 1):
                if p[j - 1] == '*':
                    if verifica_correspondencia(i - 1, j - 2):
                        tabela_dp[i][j] = tabela_dp[i - 1][j] or tabela_dp[i][j - 2]
                    else:
                        tabela_dp[i][j] = tabela_dp[i][j - 2]
                else:
                    if verifica_correspondencia(i - 1, j - 1):
                        tabela_dp[i][j] = tabela_dp[i - 1][j - 1]
        
        return tabela_dp[n][m]

Código em C++

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size(), m = p.size();
        vector<vector<bool>> tabela_dp(n + 1, vector<bool>(m + 1, false));
        tabela_dp[0][0] = true;
        
        auto verifica_correspondencia = [&](int idx_s, int idx_p) {
            if (idx_s < 0 || idx_p < 0) return false;
            if (p[idx_p] == '.') return true;
            return s[idx_s] == p[idx_p];
        };
        
        for (int i = 0; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (p[j - 1] == '*') {
                    if (verifica_correspondencia(i - 1, j - 2)) {
                        tabela_dp[i][j] = tabela_dp[i - 1][j] || tabela_dp[i][j - 2];
                    } else {
                        tabela_dp[i][j] = tabela_dp[i][j - 2];
                    }
                } else if (verifica_correspondencia(i - 1, j - 1)) {
                    tabela_dp[i][j] = tabela_dp[i - 1][j - 1];
                }
            }
        }
        return tabela_dp[n][m];
    }
};

Tags: LeetCode programação-dinâmica expressões-regulares Python cplusplus

Publicado em 7-8 02:26