Find number of times a string occurs as a subsequence in given string

Given two strings, find the number of times the second string occurs in the first string, whether continuous or discontinuous.

Examples:

Input:  
string a = "GeeksforGeeks"
string b = "Gks"

Output: 4

Explanation:  
The four strings are - (Check characters marked in bold)
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks

If we carefully analyze the given problem, we can see that it can be easily divided into sub-problems. The idea is to process all characters of both strings one by one staring from either from left or right side. Let us traverse from right corner, there are two possibilities for every pair of character being traversed.

m: Length of str1 (first string)
n: Length of str2 (second string)

If last characters of two strings are same, 
   1. We consider last characters and get count for remaining 
      strings. So we recur for lengths m-1 and n-1. 
   2. We can ignore last character of first string and 
      recurse for lengths m-1 and n.
else 
If last characters are not same, 
   We ignore last character of first string and 
   recurse for lengths m-1 and n.

Below is the implementation of above Naive recursive solution –

C++



filter_none

edit
close

play_arrow

link
brightness_4
code

// A Naive recursive C++ program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
#include <iostream>
using namespace std;
  
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b, int m, int n)
{
    // If both first and second string is empty,
    // or if second string is empty, return 1
    if ((m == 0 && n == 0) || n == 0)
        return 1;
  
    // If only first string is empty and second
    // string is not empty, return 0
    if (m == 0)
        return 0;
  
    // If last characters are same
    // Recur for remaining strings by
    // 1. considering last characters of both strings
    // 2. ignoring last character of first string
    if (a[m - 1] == b[n - 1])
        return count(a, b, m - 1, n - 1) +
               count(a, b, m - 1, n);
    else
        // If last characters are different, ignore 
        // last char of first string and recur for 
        // remaining string
        return count(a, b, m - 1, n);
}
  
// Driver code
int main()
{
    string a = "GeeksforGeeks";
    string b = "Gks";
  
    cout << count(a, b, a.size(), b.size()) << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Naive recursive java program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
import java.io.*;
  
class GFG 
{
      
    // Recursive function to find the number of times
    // the second string occurs in the first string,
    // whether continuous or discontinuous
    static int count(String a, String b, int m, int n)
    {
        // If both first and second string is empty,
        // or if second string is empty, return 1
        if ((m == 0 && n == 0) || n == 0)
            return 1;
      
        // If only first string is empty and 
        // second string is not empty, return 0
        if (m == 0)
            return 0;
      
        // If last characters are same
        // Recur for remaining strings by
        // 1. considering last characters of 
        // both strings
        // 2. ignoring last character of 
        // first string
        if (a.charAt(m - 1) == b.charAt(n - 1))
            return count(a, b, m - 1, n - 1) +
                   count(a, b, m - 1, n);
        else
            // If last characters are different,  
            // ignore last char of first string 
            // and recur for  remaining string
            return count(a, b, m - 1, n);
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        String a = "GeeksforGeeks";
        String b = "Gks";
        System.out.println( count(a, b, a.length(), b.length())) ;
      
    }
}
  
// This code is contributed by vt_m

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# A Naive recursive Python program 
# to find the number of times the 
# second string occurs in the first 
# string, whether continuous or 
# discontinuous 
  
# Recursive function to find the 
# number of times the second string
# occurs in the first string, 
# whether continuous or discontinuous 
def count(a, b, m, n): 
  
    # If both first and second string 
    # is empty, or if second string 
    # is empty, return 1 
    if ((m == 0 and n == 0) or n == 0): 
        return 1
  
    # If only first string is empty 
    # and second string is not empty,
    # return 0 
    if (m == 0):
        return 0
  
    # If last characters are same 
    # Recur for remaining strings by 
    # 1. considering last characters 
    #    of both strings 
    # 2. ignoring last character 
    #    of first string 
    if (a[m - 1] == b[n - 1]): 
        return (count(a, b, m - 1, n - 1) + 
                count(a, b, m - 1, n)) 
    else:
          
        # If last characters are different, 
        # ignore last char of first string 
        # and recur for remaining string 
        return count(a, b, m - 1, n) 
  
# Driver code 
a = "GeeksforGeeks"
b = "Gks"
  
print(count(a, b, len(a),len(b)))
  
# This code is contributed by ash264

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Naive recursive C# program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
using System;
   
class GFG 
{
       
    // Recursive function to find the number of times
    // the second string occurs in the first string,
    // whether continuous or discontinuous
    static int count(string a, string b, int m, int n)
    {
        // If both first and second string is empty,
        // or if second string is empty, return 1
        if ((m == 0 && n == 0) || n == 0)
            return 1;
       
        // If only first string is empty and 
        // second string is not empty, return 0
        if (m == 0)
            return 0;
       
        // If last characters are same
        // Recur for remaining strings by
        // 1. considering last characters of 
        // both strings
        // 2. ignoring last character of 
        // first string
        if (a[m - 1] == b[n - 1])
            return count(a, b, m - 1, n - 1) +
                   count(a, b, m - 1, n);
        else
            // If last characters are different,  
            // ignore last char of first string 
            // and recur for  remaining string
            return count(a, b, m - 1, n);
    }
       
    // Driver code
    public static void Main () 
    {
        string a = "GeeksforGeeks";
        string b = "Gks";
        Console.Write( count(a, b, a.Length, b.Length) );
       
    }
}
   
// This code is contributed by nitin mittal

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php 
// A Naive recursive PHP program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
   
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
function count_1($a, $b, $m, $n)
{
    // If both first and second string is empty,
    // or if second string is empty, return 1
    if (($m == 0 && $n == 0) || $n == 0)
        return 1;
   
    // If only first string is empty and second
    // string is not empty, return 0
    if ($m == 0)
        return 0;
   
    // If last characters are same
    // Recur for remaining strings by
    // 1. considering last characters of both strings
    // 2. ignoring last character of first string
    if ($a[$m - 1] == $b[$n - 1])
        return count_1($a, $b, $m - 1, $n - 1) +
               count_1($a, $b, $m - 1, $n);
    else
        // If last characters are different, ignore 
        // last char of first string and recur for 
        // remaining string
        return count_1($a, $b, $m - 1, $n);
}
   
// Driver code
  
$a = "GeeksforGeeks";
$b = "Gks";
echo count_1($a, $b, strlen($a), strlen($b)) ."\n";
return 0;
?>

chevron_right



Output:

4

The time complexity of above solution is exponential. If we carefully analyze, we can see that many sub-problems are solved again and again. Since same sub-problems are called again, this problem has Overlapping sub-problems property. So the problem has both properties (see this and this) of a dynamic programming problem. Like other typical Dynamic Programming problems, re-computations of same sub-problems can be avoided by constructing a temporary array that stores results of sub-problems.

Below is its implementation using Dynamic Programming –

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Dynamic Programming based C++ program to find the
// number of times the second string occurs in the first
// string, whether continuous or discontinuous
#include <iostream>
using namespace std;
  
// Iterative DP function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b)
{
    int m = a.length();
    int n = b.length();
  
    // Create a table to store results of sub-problems
    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 manner
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            // If last characters are same, 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];
}
  
// Driver code
int main()
{
    string a = "GeeksforGeeks";
    string b = "Gks";
  
    cout << count(a, b);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Dynamic Programming based 
// Java program to find the 
// number of times the second 
// string occurs in the first
// string, whether continuous 
// or discontinuous
import java.io.*;
  
class GFG 
{
      
// Iterative DP function to 
// find the number of times 
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
    int m = a.length();
    int n = b.length();
  
    // Create a table to store
    // results of sub-problems
    int lookup[][] = new int[m + 1][n + 1];
  
    // 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 manner
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            // If last characters are 
            // same, we have two options -
            // 1. consider last characters 
            //    of both strings in solution
            // 2. ignore last character
            //    of first string
            if (a.charAt(i - 1) == b.charAt(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];
}
  
// Driver Code
public static void main (String[] args)
{
    String a = "GeeksforGeeks";
    String b = "Gks";
      
    System.out.println(count(a, b));
}
}
  
// This code is contributed by anuj_67.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Dynamic Programming based 
// C# program to find the 
// number of times the second 
// string occurs in the first
// string, whether continuous 
// or discontinuous
using System;
  
class GFG 
{
      
// Iterative DP function to 
// find the number of times 
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
    int m = a.Length;
    int n = b.Length;
  
    // Create a table to store
    // results of sub-problems
    int[,] lookup = new int[m + 1, n + 1];
  
    // 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 manner
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            // If last characters are 
            // same, 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];
}
  
// Driver Code
public static void Main()
{
    String a = "GeeksforGeeks";
    String b = "Gks";
      
    Console.WriteLine(count(a, b));
}
}
  
// This code is contributed 
// by Akanksha Rai(Abby_akku)

chevron_right


Output:

4

Time complexity of above solutions is O(MN).
Auxiliary space used by the program is O(MN).

This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.GeeksforGeeks.org or mail your article to contribute@GeeksforGeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up