Count common subsequence in two strings
Last Updated :
08 Mar, 2024
Given two string S and T. 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++
#include <bits/stdc++.h>
using namespace std;
int CommonSubsequencesCount(string s, string t)
{
int n1 = s.length();
int n2 = t.length();
int dp[n1+1][n2+1];
for ( int i = 0; i <= n1; i++) {
for ( int j = 0; j <= n2; j++) {
dp[i][j] = 0;
}
}
for ( int i = 1; i <= n1; i++) {
for ( int j = 1; j <= n2; j++) {
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];
}
int main()
{
string s = "ajblqcpdz" ;
string t = "aefcnbtdi" ;
cout << CommonSubsequencesCount(s, t) << endl;
return 0;
}
|
Java
public class GFG {
static int CommonSubsequencesCount(String s, String t)
{
int n1 = s.length();
int n2 = t.length();
int dp[][] = new int [n1+ 1 ][n2+ 1 ];
char ch1,ch2 ;
for ( int i = 0 ; i <= n1; i++) {
for ( int j = 0 ; j <= n2; j++) {
dp[i][j] = 0 ;
}
}
for ( int i = 1 ; i <= n1; i++) {
for ( int j = 1 ; j <= n2; j++) {
ch1 = s.charAt(i - 1 );
ch2 = t.charAt(j - 1 );
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 ];
}
}
return dp[n1][n2];
}
public static void main (String args[]){
String s = "ajblqcpdz" ;
String t = "aefcnbtdi" ;
System.out.println(CommonSubsequencesCount(s, t));
}
}
|
C#
using System;
class GFG
{
static int CommonSubsequencesCount( string s,
string t)
{
int n1 = s.Length;
int n2 = t.Length;
int [,] dp = new int [n1 + 1, n2 + 1];
for ( int i = 0; i <= n1; i++)
{
for ( int j = 0; j <= n2; j++)
{
dp[i, j] = 0;
}
}
for ( int i = 1; i <= n1; i++)
{
for ( int j = 1; j <= n2; j++)
{
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];
}
public static void Main ()
{
string s = "ajblqcpdz" ;
string t = "aefcnbtdi" ;
Console.Write(CommonSubsequencesCount(s, t));
}
}
|
Javascript
<script>
function CommonSubsequencesCount(s, t)
{
var n1 = s.length;
var n2 = t.length;
var dp = Array.from(Array(n1+1), ()=> Array(n2+1));
for ( var i = 0; i <= n1; i++) {
for ( var j = 0; j <= n2; j++) {
dp[i][j] = 0;
}
}
for ( var i = 1; i <= n1; i++) {
for ( var j = 1; j <= n2; j++) {
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];
}
var s = "ajblqcpdz" ;
var t = "aefcnbtdi" ;
document.write( CommonSubsequencesCount(s, t));
</script>
|
PHP
<?php
function CommonSubsequencesCount( $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 ( $i = 1; $i <= $n1 ; $i ++)
{
for ( $j = 1; $j <= $n2 ; $j ++)
{
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 ];
}
$s = "ajblqcpdz" ;
$t = "aefcnbtdi" ;
echo CommonSubsequencesCount( $s , $t ) . "\n" ;
?>
|
Python3
def CommonSubsequencesCount(s, t):
n1 = len (s)
n2 = len (t)
dp = [[ 0 for i in range (n2 + 1 )]
for i in range (n1 + 1 )]
for i in range ( 1 , n1 + 1 ):
for j in range ( 1 , n2 + 1 ):
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]
s = "ajblqcpdz"
t = "aefcnbtdi"
print (CommonSubsequencesCount(s, t))
|
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++
#include <bits/stdc++.h>
using namespace std;
int CommonSubsequencesCount(string s, string t)
{
int n1 = s.length();
int n2 = t.length();
vector< int >prev(n2+1 , 0);
for ( int i = 1; i <= n1; i++) {
vector< int >curr(n2 +1 , 0);
for ( int j = 1; j <= n2; j++) {
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];
}
prev = curr;
}
return prev[n2];
}
int main()
{
string s = "ajblqcpdz" ;
string t = "aefcnbtdi" ;
cout << CommonSubsequencesCount(s, t) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int CommonSubsequencesCount(String s, String t) {
int n1 = s.length();
int n2 = t.length();
int [] prev = new int [n2 + 1 ];
for ( int i = 1 ; i <= n1; i++) {
int [] curr = new int [n2 + 1 ];
for ( int j = 1 ; j <= n2; j++) {
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 ];
}
}
prev = curr;
}
return prev[n2];
}
public static void main(String[] args) {
String s = "ajblqcpdz" ;
String t = "aefcnbtdi" ;
System.out.println(CommonSubsequencesCount(s, t));
}
}
|
C#
using System;
public class CommonSubsequenceCount {
public static int Count( string s, string t)
{
int n1 = s.Length;
int n2 = t.Length;
int [] prev = new int [n2 + 1];
for ( int i = 1; i <= n1; i++) {
int [] curr = new int [n2 + 1];
for ( int j = 1; j <= n2; j++) {
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];
}
prev = curr;
}
return prev[n2];
}
public static void Main()
{
string s = "ajblqcpdz" ;
string t = "aefcnbtdi" ;
Console.WriteLine(Count(s, t));
}
}
|
Javascript
function CommonSubsequencesCount(s, t) {
let n1 = s.length;
let n2 = t.length;
let prev = new Array(n2+1).fill(0);
for (let i = 1; i <= n1; i++) {
let curr = new Array(n2 + 1).fill(0);
for (let j = 1; j <= n2; j++) {
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];
}
prev = curr;
}
return prev[n2];
}
let s = "ajblqcpdz" ;
let t = "aefcnbtdi" ;
console.log(CommonSubsequencesCount(s, t));
|
Python3
def CommonSubsequencesCount(s, t):
n1 = len (s)
n2 = len (t)
prev = [ 0 ] * (n2 + 1 )
for i in range ( 1 , n1 + 1 ):
curr = [ 0 ] * (n2 + 1 )
for j in range ( 1 , n2 + 1 ):
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 ]
prev = curr
return prev[n2]
if __name__ = = "__main__" :
s = "ajblqcpdz"
t = "aefcnbtdi"
print (CommonSubsequencesCount(s, t))
|
Time Complexity : O(n1 * n2)
Auxiliary Space : O(n2)
Share your thoughts in the comments
Please Login to comment...