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)
Similar Reads
Count Distinct Subsequences
Given a string str of length n, your task is to find the count of distinct subsequences of it. Examples: Input: str = "gfg"Output: 7Explanation: The seven distinct subsequences are "", "g", "f", "gf", "fg", "gg" and "gfg" Input: str = "ggg"Output: 4Explanation: The four distinct subsequences are "",
14 min read
Count common characters in two strings
Given two strings s1 and s2 consisting of lowercase English alphabets, the task is to count all the pairs of indices (i, j) from the given strings such that s1[i] = s2[j] and all the indices are distinct i.e. if s1[i] pairs with some s2[j] then these two characters will not be paired with any other
5 min read
Count of 'GFG' Subsequences in the given string
Given a string of length n of capital letters. The task is to find the count of 'GFG' subsequence in the given string. Examples: Input : str[] = "GFGFG" Output : 4 GFGFG, GFGFG, GFGFG, GFGFG Input : str[] = "ABCFGFPG" Output : 1 To find the number of "GFG" subsequences in the given string, observe f
5 min read
Count subsequence of length three in a given string
Given a string of length n and a subsequence of length 3. Find the total number of occurrences of the subsequence in this string. Examples : Input : string = "GFGFGYSYIOIWIN", subsequence = "GFG" Output : 4 Explanation : There are 4 such subsequences as shown: GFGFGYSYIOIWIN GFGFGYSYIOIWIN GFGFGYSYI
15 min read
Counting common prefix/suffix strings in two lists
Given two Lists of strings s1 and s2, you have to count the number of strings in s2 which is either a suffix or prefix of at least one string of s1. Examples: Input: s1 = ["cat", "catanddog", "lion"], s2 = ["cat", "dog", "rat"]Output: 2Explanation: String "cat" of s2 is a prefix of "catanddog"string
4 min read
Printing Longest Common Subsequence | Set 2 (Printing All)
Given two sequences, print all longest subsequence present in both of them.Examples: Input: string X = "AGTGATG" string Y = "GTTAG" Output: GTAG GTTG Input: string X = "AATCC" string Y = "ACACG" Output: ACC AAC Input: string X = "ABCBDAB" string Y = "BDCABA" Output: BCAB BCBA BDAB We have discussed
12 min read
Count Permutations in a Sequence
Given an array A consisting of N positive integers, find the total number of subsequences of the given array such that the chosen subsequence represents a permutation. Note: Sequence A is a subsequence of B if A can be obtained from B by deleting some(possibly, zero) elements without changing its or
5 min read
Check if two strings have a common substring
You are given two strings str1 and str2. You have to check if the two strings share a common substring. Examples : Input : str1 = "HELLO" str2 = "WORLD" Output : YES Explanation : The substrings "O" and "L" are common to both str1 and str2 Input : str1 = "HI" str2 = "ALL" Output : NO Explanation : B
5 min read
Count the strings that are subsequence of the given string
Given a string S and an array arr[] of words, the task is to return the number of words from the array which is a subsequence of S. Examples: Input: S = âprogrammingâ, arr[] = {"prom", "amin", "proj"}Output: 2Explanation: "prom" and "amin" are subsequence of S while "proj" is not) Input: S = âgeeksf
11 min read
Count of N length Strings having S as a Subsequence
Given a string S and an integer N, the task is to calculate the number of strings of length N consisting of only lowercase characters which have S as one of its subsequences. Note: As the answer can be very large return it modulo 10^9+7. Examples: Input: N = 3, S = "abc"Output: 1Explanation: There a
10 min read