0

I'm working on a longest common subsequence program and for some reason my array keeps being filled with garbage even after I init everything inside of it to NULL.

    #include "main.h"

    int main()
    {
        //Provided char arrays containing sequences
        char X[] = { ' ', 's', 'k', 'u', 'l', 'l', 'a', 'n', 'd', 'c', 'r', 'o', 's', 's', 'b', 'o', 'n', 'e', 's' };
        char Y[] = { ' ', 'l', 'u', 'l', 'l', 'a', 'b', 'i', 'e', 's', 'f', 'o', 'r', 'b', 'a', 'b', 'i', 'e', 's' };

    //Char array that will contain the directions
    //for the longest subsequence
    char b[ARRAY_ROW][ARRAY_COL];

    int c[ARRAY_ROW][ARRAY_COL];

    //Envoking LCS function
    LongestCommonSubsequence(X, Y, b, c);

    int row = ARRAY_ROW;
    int col = ARRAY_COL;

    //Envoking traverse function
    Traverse(b, X, row, col);

    cout << "END PHASE" << endl;

    return 0;
}

void LongestCommonSubsequence(char x[], char y[], char b[ARRAY_ROW][ARRAY_COL], int c[ARRAY_ROW][ARRAY_COL])
{
    //hardcoded length look back here
    int m = ARRAY_ROW - 1;
    int n = ARRAY_COL - 1;

    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            c[i][j] = 0;
            b[i][j] = 0;
        }
    }

    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (x[i] == y[j])
            {
                c[i][j] = c[i - 1][j - 1] + 1;
                b[i][j] = '\\';
            }
            else if (c[i - 1][j] >= c[i][j - 1])
            {
                c[i][j] = c[i - 1][j];
                b[i][j] = '|';
            }
            else
            {
                c[i][j] = c[i][j - 1];
                b[i][j] = '-';
            }
        }
    }

    return;
}

void Traverse(char b[][ARRAY_COL], char x[], int i, int j)
{

    if (i == 0 || j == 0)
        return;
    if (b[i][j] == '\\')
    {
        Traverse(b, x, i - 1, j - 1);
        cout << x[i];
    }
    else if (b[i][j] == '|')
    {
        Traverse(b, x, i - 1, j);
    }
    else
    {
        Traverse(b, x, i, j - 1);
    }
    return;
}

in my LongestCommonSubsequence function the first thing I do is init the 2D array to NULL with hard coded sizes. However after I init the array it is still filled with garbage. So when I hit my Traverse function none of the if statements get hit because it never equals those characters.

ryandonohue
  • 189
  • 4
  • 22
  • When you used the debugger, which statement is causing the issue? What are the values of the variables in use by the statement? – Thomas Matthews Nov 11 '15 at 00:11
  • `for (int i = 0; i < 50; i++) for (int j = 0; j < 50; j++) cout << b[i][j];` why do you go until `50`? are you sure you have that many elements in your bidimensional array? – A.S.H Nov 11 '15 at 00:21
  • @A.S.H sorry that was just for testing, I just removed that. – ryandonohue Nov 11 '15 at 00:21
  • @ThomasMatthews for the Transverse fuction it is filled with things such as "skullandcrossbone" when it should only ever be filled with / | or - – ryandonohue Nov 11 '15 at 00:25
  • What are the values of `ARRAY_ROW and ARRAY_COL`? trying to reproduce exactly – A.S.H Nov 11 '15 at 00:27
  • @A.S.H sorry those are in my .h const int ARRAY_ROW = 19; const int ARRAY_COL = 19; – ryandonohue Nov 11 '15 at 00:28
  • 1
    Well, probably the garbage was due to printing up to 50. If you fix it you wont have garbage, but you may have other problems to continue getting your algorithm to work. – A.S.H Nov 11 '15 at 00:40
  • `b[i][j] = NULL;` should be `b[i][j] = 0;` . Also you do not zero the last index in both dimensions there, was that intentional? – M.M Nov 11 '15 at 00:42
  • The question should include compilable code that reproduces the problem, and an explanation of how the program's behaviour differs from what you expected. I see you made an edit, have you verified that the problem still occurs when you run the edited code? – M.M Nov 11 '15 at 00:43
  • @MM the strings are never accessed as strings,so this should be ok, although not adviceable of course. – A.S.H Nov 11 '15 at 00:43
  • @A.S.H well the code `c[i][j] = c[i][j - 1];` will read an uninitialized variable when `i == m` – M.M Nov 11 '15 at 00:45
  • @M.M sorry I did make a few small changes. Nothing crazy. This is my whole program minus the declaration of the globals in the header and the function headers. – ryandonohue Nov 11 '15 at 00:48
  • I confirm that the program is compilable and verifiable. The output after fixing the `50` issue is empty. So all what you need now is to take your algorithm to work correctly. – A.S.H Nov 11 '15 at 00:50
  • @ryandonohue fix the "minuses". You have to post exactly what is compiled otherwise we are guessing – M.M Nov 11 '15 at 00:54

1 Answers1

0

I found the solution! When I was calling the Traverse function

int row = ARRAY_ROW;
int col = ARRAY_COL;

//Envoking traverse function
Traverse(b, X, row, col);

I was passing in 19 and 19 for the last two arguments. Then in my Traverse function

void Traverse(char b[][ARRAY_COL], char x[], int i, int j)
{
    if (i == 0 || j == 0)
        return;
    if (b[i][j] == '\\')
    {
        Traverse(b, x, i - 1, j - 1);
        cout << x[i];
    }
    else if (b[i][j] == '|')
    {
        Traverse(b, x, i - 1, j);
    }
    else
    {
        Traverse(b, x, i, j - 1);
    }
    return;
}

We were trying to start by reading b[19][19] which doesn't exist because our array only goes b[0-18][0-18].

Then we fixed it by adding

int row = ARRAY_ROW - 1;
int col = ARRAY_COL - 1;

//Envoking traverse function
Traverse(b, X, row, col);

and now we are able to find the longest common subsequence.

ryandonohue
  • 189
  • 4
  • 22