Count common subsequence in two strings

Given two string S and Q. The task is to count the number of the common subsequence in S and T.
Examples:
Input : S = “ajblqcpdz”, T = “aefcnbtdi”
Output : 11
Common subsequences are : { “a”, “b”, “c”, “d”, “ab”, “bd”, “ad”, “ac”, “cd”, “abd”, “acd” }Input : S = “a”, T = “ab”
Output : 1
To find the number of common subsequences in two string, say S and T, we use Dynamic Programming by defining a 2D array dp[][], where dp[i][j] is the number of common subsequences in the string S[0…i-1] and T[0….j-1].
Now, we can define dp[i][j] as = dp[i][j-1] + dp[i-1][j] + 1, when S[i-1] is equal to T[j-1] 
This is because when S[i-1] == S[j-1], using the above fact all the previous common sub-sequences are doubled as they get appended by one more character. Both dp[i][j-1] and dp[i-1][j] contain dp[i-1][j-1] and hence it gets added two times in our recurrence which takes care of doubling of count of all previous common sub-sequences. Addition of 1 in recurrence is for the latest character match : common sub-sequence made up of s1[i-1] and s2[j-1]  = dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1], when S[i-1] is not equal to T[j-1] 
Here we subtract dp[i-1][j-1] once because it is present in both dp[i][j – 1] and dp[i – 1][j] and gets added twice.
Implementation:
C++
| // C++ program to count common subsequence in two strings#include <bits/stdc++.h>usingnamespacestd;// return the number of common subsequence in// two stringsintCommonSubsequencesCount(string s, string t){    intn1 = s.length();    intn2 = t.length();    intdp[n1+1][n2+1];    for(inti = 0; i <= n1; i++) {        for(intj = 0; j <= n2; j++) {            dp[i][j] = 0;        }    }    // for each character of S    for(inti = 1; i <= n1; i++) {        // for each character in T        for(intj = 1; j <= n2; j++) {            // if character are same in both             // the string            if(s[i - 1] == t[j - 1])                 dp[i][j] = 1 + dp[i][j - 1] + dp[i - 1][j];                        else                dp[i][j] = dp[i][j - 1] + dp[i - 1][j] -                                         dp[i - 1][j - 1];                    }    }    returndp[n1][n2];}// Driver Programintmain(){    string s = "ajblqcpdz";    string t = "aefcnbtdi";    cout << CommonSubsequencesCount(s, t) << endl;    return0;} | 
Java
| // Java program to count common subsequence in two stringspublicclassGFG {        // return the number of common subsequence in     // two strings     staticintCommonSubsequencesCount(String s, String t)     {         intn1 = s.length();         intn2 = t.length();         intdp[][] = newint[n1+1][n2+1];         charch1,ch2 ;              for(inti = 0; i <= n1; i++) {             for(intj = 0; j <= n2; j++) {                 dp[i][j] = 0;             }         }               // for each character of S         for(inti = 1; i <= n1; i++) {                   // for each character in T             for(intj = 1; j <= n2; j++) {                                 ch1 = s.charAt(i - 1);                ch2 = t.charAt(j - 1);                                // if character are same in both                  // the string                                 if(ch1 == ch2)                      dp[i][j] = 1+ dp[i][j - 1] + dp[i - 1][j];                             else                    dp[i][j] = dp[i][j - 1] + dp[i - 1][j] -                                              dp[i - 1][j - 1];                         }         }               returndp[n1][n2];     }     // Driver code     publicstaticvoidmain (String args[]){                  String s = "ajblqcpdz";           String t = "aefcnbtdi";                   System.out.println(CommonSubsequencesCount(s, t));               }// This code is contributed by ANKITRAI1} | 
Python3
| # Python3 program to count common# subsequence in two strings# return the number of common subsequence # in two stringsdefCommonSubsequencesCount(s, t):    n1 =len(s)    n2 =len(t)    dp =[[0fori inrange(n2 +1)]              fori inrange(n1 +1)]    # for each character of S    fori inrange(1, n1 +1):        # for each character in T        forj inrange(1, n2 +1):            # if character are same in both             # the string            if(s[i -1] ==t[j -1]):                dp[i][j] =(1+dp[i][j -1] +                                dp[i -1][j])                     else:                dp[i][j] =(dp[i][j -1] +dp[i -1][j] -                            dp[i -1][j -1])                     returndp[n1][n2]# Driver Codes ="ajblqcpdz"t ="aefcnbtdi"print(CommonSubsequencesCount(s, t))# This code is contributed by Mohit Kumar | 
C#
| // C# program to count common // subsequence in two stringsusingSystem;classGFG {// return the number of common // subsequence in two strings staticintCommonSubsequencesCount(strings,                                    stringt) {     intn1 = s.Length;     intn2 = t.Length;     int[,] dp = newint[n1 + 1, n2 + 1];         for(inti = 0; i <= n1; i++)     {         for(intj = 0; j <= n2; j++)         {             dp[i, j] = 0;         }     }         // for each character of S     for(inti = 1; i <= n1; i++)    {             // for each character in T         for(intj = 1; j <= n2; j++)        {                        // if character are same in             // both the string                             if(s[i - 1] == t[j - 1])                 dp[i, j] = 1 + dp[i, j - 1] +                               dp[i - 1, j];                         else                dp[i, j] = dp[i, j - 1] +                            dp[i - 1, j] -                            dp[i - 1, j - 1];                     }     }         returndp[n1, n2]; } // Driver code publicstaticvoidMain (){    strings = "ajblqcpdz";     stringt = "aefcnbtdi";             Console.Write(CommonSubsequencesCount(s, t)); }}// This code is contributed// by ChitraNayal | 
Javascript
| <script>// Javascript program to count common subsequence in two strings// return the number of common subsequence in// two stringsfunctionCommonSubsequencesCount(s, t){    varn1 = s.length;    varn2 = t.length;    vardp = Array.from(Array(n1+1), ()=> Array(n2+1));    for(vari = 0; i <= n1; i++) {        for(varj = 0; j <= n2; j++) {            dp[i][j] = 0;        }    }    // for each character of S    for(vari = 1; i <= n1; i++) {        // for each character in T        for(varj = 1; j <= n2; j++) {            // if character are same in both             // the string            if(s[i - 1] == t[j - 1])                 dp[i][j] = 1 + dp[i][j - 1] + dp[i - 1][j];                        else                dp[i][j] = dp[i][j - 1] + dp[i - 1][j] -                                         dp[i - 1][j - 1];                    }    }    returndp[n1][n2];}// Driver Programvars = "ajblqcpdz";vart = "aefcnbtdi";document.write( CommonSubsequencesCount(s, t));</script> | 
PHP
| <?php// PHP program to count common subsequence// in two strings// return the number of common subsequence// in two stringsfunctionCommonSubsequencesCount($s, $t){    $n1= strlen($s);    $n2= strlen($t);    $dp= array();    for($i= 0; $i<= $n1; $i++)     {        for($j= 0; $j<= $n2; $j++)        {            $dp[$i][$j] = 0;        }    }    // for each character of S    for($i= 1; $i<= $n1; $i++)     {        // for each character in T        for($j= 1; $j<= $n2; $j++)        {            // if character are same in both             // the string            if($s[$i- 1] == $t[$j- 1])                 $dp[$i][$j] = 1 + $dp[$i][$j- 1] +                                   $dp[$i- 1][$j];                 else                $dp[$i][$j] = $dp[$i][$j- 1] +                               $dp[$i- 1][$j] -                               $dp[$i- 1][$j- 1];             }    }    return$dp[$n1][$n2];}// Driver Code$s= "ajblqcpdz";$t= "aefcnbtdi";echoCommonSubsequencesCount($s, $t) ."\n";// This code is contributed // by Akanksha Rai?> | 
11
Complexity Analysis:
- Time Complexity : O(n1 * n2)
- Auxiliary Space : O(n1 * n2)
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector prev of size n2+1 and initialize it with 0.
- Set a base case by initializing the values of prev.
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- Now Create a temporary 1d vector curr used to store the current values from previous computations.
- After every iteration assign the value of curr to prev for further iteration.
- At last return and print the final answer stored in prev[n2]
Implementation: 
 
C++
| // C++ program to count common subsequence in two strings#include <bits/stdc++.h>usingnamespacestd;// return the number of common subsequence in// two stringsintCommonSubsequencesCount(string s, string t){    intn1 = s.length();    intn2 = t.length();        // to store previous computaions of subproblems    vector<int>prev(n2+1 , 0);    // for each character of S    for(inti = 1; i <= n1; i++) {        vector<int>curr(n2 +1 , 0);        // for each character in T        for(intj = 1; j <= n2; j++) {            // if character are same in both            // the string            if(s[i - 1] == t[j - 1])                curr[j] = 1 + curr[j - 1] + prev[j];                    else                curr[j] = curr[j - 1] + prev[j] - prev[j - 1];                }                    // assigning values         // for iterate further        prev = curr;    }        // return final answer    returnprev[n2];}// Driver Programintmain(){    string s = "ajblqcpdz";    string t = "aefcnbtdi";    cout << CommonSubsequencesCount(s, t) << endl;    return0;} | 
Java
| importjava.util.*;publicclassMain {    // Function to count the number of common subsequences in two strings    publicstaticintCommonSubsequencesCount(String s, String t) {        intn1 = s.length();        intn2 = t.length();        // To store previous computations of subproblems        int[] prev = newint[n2 + 1];        // For each character of S        for(inti = 1; i <= n1; i++) {            int[] curr = newint[n2 + 1];            // For each character in T            for(intj = 1; j <= n2; j++) {                // If characters are same in both the strings                if(s.charAt(i - 1) == t.charAt(j - 1)) {                    curr[j] = 1+ curr[j - 1] + prev[j];                } else{                    curr[j] = curr[j - 1] + prev[j] - prev[j - 1];                }            }            // Assigning values for further iterations            prev = curr;        }        // Return the final answer        returnprev[n2];    }    // Driver program    publicstaticvoidmain(String[] args) {        String s = "ajblqcpdz";        String t = "aefcnbtdi";        System.out.println(CommonSubsequencesCount(s, t));    }} | 
Python3
| defCommonSubsequencesCount(s, t):    n1 =len(s)    n2 =len(t)    # to store previous computations of subproblems    prev =[0] *(n2 +1)    # for each character of S    fori inrange(1, n1 +1):        curr =[0] *(n2 +1)        # for each character in T        forj inrange(1, n2 +1):            # if characters are the same in both strings            ifs[i -1] ==t[j -1]:                curr[j] =1+curr[j -1] +prev[j]            else:                curr[j] =curr[j -1] +prev[j] -prev[j -1]        # assigning values for iteration        prev =curr        # return the final answer    returnprev[n2]# Driver Programif__name__ =="__main__":    s ="ajblqcpdz"    t ="aefcnbtdi"    print(CommonSubsequencesCount(s, t)) | 
C#
| usingSystem;publicclassCommonSubsequenceCount {    // return the number of common subsequence in    // two strings    publicstaticintCount(strings, stringt)    {        intn1 = s.Length;        intn2 = t.Length;        // to store previous computations of subproblems        int[] prev = newint[n2 + 1];        // for each character of S        for(inti = 1; i <= n1; i++) {            int[] curr = newint[n2 + 1];            // for each character in T            for(intj = 1; j <= n2; j++) {                // if characters are the same in both                // strings                if(s[i - 1] == t[j - 1])                    curr[j] = 1 + curr[j - 1] + prev[j];                else                    curr[j] = curr[j - 1] + prev[j]                              - prev[j - 1];            }            // assign values for further iteration            prev = curr;        }        // return final answer        returnprev[n2];    }    publicstaticvoidMain()    {        strings = "ajblqcpdz";        stringt = "aefcnbtdi";        Console.WriteLine(Count(s, t));    }} | 
Javascript
| // Javascript program to count common subsequence in two strings// return the number of common subsequence in// two stringsfunctionCommonSubsequencesCount(s, t) {    let n1 = s.length;    let n2 = t.length;        // to store previous computaions of subproblems    let prev = newArray(n2+1).fill(0);        // for each character of s    for(let i = 1; i <= n1; i++) {        let curr = newArray(n2 + 1).fill(0);        // for each character in t        for(let j = 1; j <= n2; j++) {            // if character are same in both            // the string            if(s[i - 1] === t[j - 1])                curr[j] = 1 + curr[j - 1] + prev[j];                    else                curr[j] = curr[j - 1] + prev[j] - prev[j - 1];                }        // assigning values         // for iterate further        prev = curr;    }    // return final answer    returnprev[n2];}// Driver Programlet s = "ajblqcpdz";let t = "aefcnbtdi";console.log(CommonSubsequencesCount(s, t)); | 
11
Time Complexity : O(n1 * n2) 
Auxiliary Space : O(n2)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!
 
				 
					


