0

Given the following algorithm to count the number of times a string appears as a subsequence of another and give me the final number, how would I implement a routine to give me the indices of the strings. eg if there are 4 string appearing as a subsequence of another how would I find the indices of each string? [1][4][9] the first string From my own attempts to solve the problem there is a pattern on the dp lookup table which I see visually but struggle to implement in code, how would I add a backtracking that would give me the indices of each string subsequence as it appears. In the example I know the number of times the string will appear as a subsequence but I want to know the string indices of each subsequence appearance, as stated I can determine this visually when I look at the lookup table values but struggle to code it? I know the solution lies in the backtracking the tabular lookup container

int count(string a, string b)
{
    int m = a.length();
    int n = b.length();


    int lookup[m + 1][n + 1] = { { 0 } };

    // If first string is empty
    for (int i = 0; i <= n; ++i)
        lookup[0][i] = 0;

    // If second string is empty
    for (int i = 0; i <= m; ++i)
        lookup[i][0] = 1;

    // Fill lookup[][] in bottom up 
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            // we have two options 
            //
            // 1. consider last characters of both strings
            //    in solution
            // 2. ignore last character of first string
            if (a[i - 1] == b[j - 1])
                lookup[i][j] = lookup[i - 1][j - 1] + 
                               lookup[i - 1][j];

            else
                // If last character are different, ignore
                // last character of first string
                lookup[i][j] = lookup[i - 1][j];
        }
    }

    return lookup[m][n];
}
int main(void){
string a = "ccaccbbbaccccca";
string b = "abc";

cout << count(a, b);

return 0;

}
Rza
  • 19
  • 1
  • 12

1 Answers1

0

You can do it recursively (essentially you'll just be doing the same thing in another direction):

def gen(i, j):
     // If there's no match, we're done
     if lookup[i][j] == 0:
        return []
     // If one of the indices is 0, the answer is an empty list
     // which means an empty sequence
     if i == 0 or j == 0:
         return [[]]
     // Otherwise, we just do all transitions backwards
     // combine the results
     res = []
     if a[i - 1] == b[j - 1]:
         res = gen(i - 1, j - 1)
         for elem in res:
              elem.append(a[i - 1])
     return res + gen(i - 1, j)

The idea is to do exactly the same thing we use to compute the answer, but to return a list of indices instead of the number of ways.

I haven't tested the code above, so it may contain minor bugs, but I think the idea is clear.

kraskevich
  • 18,368
  • 4
  • 33
  • 45