Cálculo do Substring e Subsequência Comuns Máximos entre Duas Strings

O cálculo do substring e subsequência comuns máximos entre duas strings é uma tarefa comum em ciência da computação, frequentemente resolvida através de programação dinâmica. Embora ambas as abordagens sejam semelhantes, as equações de recorrência utilziadas diferem.

Cálculo do Substring Comum Máximo:

#include <iostream>
#include <vector>
#include <string>

std::string maiorSubstringComum(const std::string& textoA, const std::string& textoB) {
    if (textoA.empty() || textoB.empty()) {
        return "";
    }

    int tamanhoMaximo = 0, posicaoFim = 0;
    std::vector<:vector>> tabela(textoA.size(), std::vector<int>(textoB.size(), 0));

    for (size_t i = 0; i < textoA.size(); ++i) {
        for (size_t j = 0; j < textoB.size(); ++j) {
            if (textoA[i] == textoB[j]) {
                if (i == 0 || j == 0) {
                    tabela[i][j] = 1;
                } else {
                    tabela[i][j] = tabela[i - 1][j - 1] + 1;
                }
                if (tabela[i][j] > tamanhoMaximo) {
                    tamanhoMaximo = tabela[i][j];
                    posicaoFim = i;
                }
            }
        }
    }
    return textoA.substr(posicaoFim - tamanhoMaximo + 1, tamanhoMaximo);
}

int main() {
    std::string entrada, strUm, strDois;
    while (std::getline(std::cin, entrada)) {
        if (strUm.empty()) {
            strUm = entrada;
        } else if (strDois.empty()) {
            strDois = entrada;
        }
        if (!strUm.empty() && !strDois.empty()) {
            std::cout << maiorSubstringComum(strUm, strDois) << std::endl;
            strUm.clear();
            strDois.clear();
        }
        entrada.clear();
    }
}</int></:vector>

Cálculo da Subsequência Comum Máxima:

A subsequência comum máxima difere do substring comum máximo em que os caracteres da subsequência não precisam ser consecutivos na string original.

#include <iostream>
#include <vector>
#include <string>

int comprimentoSubsequenciaComum(const std::string& seqA, const std::string& seqB, std::vector<std::vector<int>>& matriz, std::vector<std::vector<int>>& direcao) {
    for (size_t i = 1; i <= seqA.size(); ++i) {
        for (size_t j = 1; j <= seqB.size(); ++j) {
            if (seqA[i - 1] == seqB[j - 1]) {
                matriz[i][j] = matriz[i - 1][j - 1] + 1;
                direcao[i][j] = 1;
            } else if (matriz[i - 1][j] > matriz[i][j - 1]) {
                matriz[i][j] = matriz[i - 1][j];
                direcao[i][j] = 2;
            } else {
                matriz[i][j] = matriz[i][j - 1];
                direcao[i][j] = 3;
            }
        }
    }
    return matriz[seqA.size()][seqB.size()];
}

void exibirSubsequenciaComum(const std::vector<std::vector<int>>& direcao, const std::string& seqA, size_t linha, size_t coluna) {
    if (linha == 0 || coluna == 0) {
        return;
    }
    if (direcao[linha][coluna] == 1) {
        exibirSubsequenciaComum(direcao, seqA, linha - 1, coluna - 1);
        std::cout << seqA[linha - 1];
    } else if (direcao[linha][coluna] == 2) {
        exibirSubsequenciaComum(direcao, seqA, linha - 1, coluna);
    } else {
        exibirSubsequenciaComum(direcao, seqA, linha, coluna - 1);
    }
}

int main() {
    std::string linhaEntrada;
    std::getline(std::cin, linhaEntrada);
    std::stringstream separador(linhaEntrada);
    std::string sequenciaA, sequenciaB;
    separador >> sequenciaA >> sequenciaB;
    std::vector<std::vector<int>> matriz(sequenciaA.size() + 1, std::vector<int>(sequenciaB.size() + 1));
    std::vector<std::vector<int>> direcao(sequenciaA.size() + 1, std::vector<int>(sequenciaB.size() + 1));
    std::cout << comprimentoSubsequenciaComum(sequenciaA, sequenciaB, matriz, direcao) << std::endl;
    exibirSubsequenciaComum(direcao, sequenciaA, sequenciaA.size(), sequenciaB.size());
    return 0;
}

Tags: C++ programação-dinâmica substring subsequencia

Publicado em 8-16 19:10