Niedziałający algorytm najdłuższego wspólnego podciągu

0

Napisałem dynamiczny algorytm liczący sumę elementów najdłuższego wspólnego podciągu, lecz gdzieś jest błąd, którego od dawna nie mogę znaleźć. Proszę o pomoc. Oto mój kod:

#include<iostream>
using namespace std;
int tab1[10000];
int tab2[10000];
int tab[100][1000];


int main()
{
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
        cin>>tab1[i];
    for(int i=0; i<n; i++)
        cin>>tab2[i];

    for (int i=0; i<=n; i++)
    {

        for (int j=0; j<=n; j++)
        {
            if(i==0||j==0)
                tab[i][j]=0;
            else
            {
                if (tab1[i-1]==tab2[j-1])
                    {
                    tab[i][j] = tab[i-1][j-1]+1;
                    }
                else
                    tab[i][j] = max( tab[i-1][j], tab[i][j-1] );
            }
        }

    }

    int licznik=0;
    int i=n, j=n;
    while(i>=0&&j>=0)
    {
        if(tab1[i-1]==tab2[j-1])
        {
            licznik+=tab1[i-1];
            j--;
            i--;
        }
        else
        {
            if(tab[i-1][j]>tab[i][j-1])
                i--;
            else
                j--;
        }
    }
    cout<<licznik;
}
1

Pierwsze co widzę to musi być int tab[1001][1001];
Aczkolwiek warto zmodyfikować koda aby wystarczyło int tabA[1000],tabB[1000],*tab[2]={tabA,tabB); obliczasz zawsze drugi wiersz, po czym robisz swap dwóch wierszy.

2

Treść zadania jest nieprecyzyjna. W przypadku istnienia większej liczby maksymalnych podciągów, nie jest określone z którego powinna być wyliczana suma.

Na przykład dla ciągów.
1 2 3 10 12 13
10 12 13 1 2 3
suma powinna wynosić 6 czy też 35 ?

1

Radziłbym zacząć od zera nie pakując wszystkiego do main.
Podziel kod na części, wczytujący dane, obliczający wynik, oraz wypisujący wynik.

Na dodatek masz błąd buffer overflow: https://godbolt.org/z/eds93cW6W (nawet po poprawce od dragona).

Problem jest tu:

    while(i>=0&&j>=0)
    {
        if(tab1[i-1]==tab2[j-1])
1

Naprawione, przez:

  • usunięcie błędu buffer overflow
  • podział na mniejsze funkcje
  • usunięcie zmiennych globalnych
int sumOfLongestSubsuquence(const std::vector<int>& a,
                            const std::vector<int>& b) {
    const int n = a.size();
    std::vector<std::vector<int>> tab(n + 1, std::vector<int>(n + 1));

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0 || j == 0)
                tab[i][j] = 0;
            else {
                if (a[i - 1] == b[j - 1]) {
                    tab[i][j] = tab[i - 1][j - 1] + 1;
                } else
                    tab[i][j] = std::max(tab[i - 1][j], tab[i][j - 1]);
            }
        }
    }

    int licznik = 0;
    int i = n, j = n;
    while (i > 0 && j > 0) {
        if (a[i - 1] == b[j - 1]) {
            licznik += a[i - 1];
            j--;
            i--;
        } else {
            if (tab[i - 1][j] > tab[i][j - 1])
                i--;
            else
                j--;
        }
    }
    return licznik;
}

https://godbolt.org/z/aaWhfachT

Disclaimer: nie wchodziłem w szczegóły implementacyjne, więc nie twierdze, że wszystko działa jak należy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1