Given two strings S and T of length N and M respectively, the task is to count the number of substrings of S that contains the string T in it as a substring.
Examples:
Input: S = “dabc”, T = “ab”
Output: 4
Explanation:
Substrings of S containing T as a substring are:
- S[0, 2] = “dab”
- S[1, 2] = “ab”
- S[1, 3] = “abc”
- S[0, 3] = “dabc”
Input: S = “hshshshs” T = “hs”
Output: 25
Naive Approach: For the simplest approach to solve the problem, refer to the previous post of this article.
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Efficient Approach: To optimize the above approach, the idea is to find out all the occurrences of T in S. Whenever T is found in S, add all the substrings which contain this occurrence of T excluding the substrings which were already calculated in the previous occurrences. Follow the steps below to solve the problem:
- Initialize a variable, say answer, to store the count of substrings.
- Initialize a variable, say last, to store the starting index of the last occurrence of T in S.
- Iterate over the range [0, N – M] using a variable, say i.
- Check if the substring S[i, i + M] is equal to T or not. If found to be true, then add (i + 1 – last) * (N – (i + M – 1)) to answer and update last to (i + 1).
- Otherwise, continue for the next iteration.
- After completing the above steps, print the value of the answer as the result.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to count the substrings of // string containing another given // string as a substring void findOccurrences(string S, string T)
{ // Store length of string S
int n1 = S.size();
// Store length of string T
int n2 = T.size();
// Store the required count of
// substrings
int ans = 0;
// Store the starting index of
// last occurrence of T in S
int last = 0;
// Iterate in range [0, n1-n2]
for ( int i = 0; i <= n1 - n2; i++) {
// Check if substring from i
// to i + n2 is equal to T
bool chk = true ;
// Check if substring from i
// to i + n2 is equal to T
for ( int j = 0; j < n2; j++) {
// Mark chk as false and
// break the loop
if (T[j] != S[i + j]) {
chk = false ;
break ;
}
}
// If chk is true
if (chk) {
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
cout << ans;
} // Driver code int main()
{ string S = "dabc" , T = "ab" ;
// Function Call
findOccurrences(S, T);
} |
// Java program for the above approach class GFG{
// Function to count the substrings of // string containing another given // string as a substring static void findOccurrences(String S, String T)
{ // Store length of string S
int n1 = S.length();
// Store length of string T
int n2 = T.length();
// Store the required count of
// substrings
int ans = 0 ;
// Store the starting index of
// last occurrence of T in S
int last = 0 ;
// Iterate in range [0, n1-n2]
for ( int i = 0 ; i <= n1 - n2; i++)
{
// Check if substring from i
// to i + n2 is equal to T
boolean chk = true ;
// Check if substring from i
// to i + n2 is equal to T
for ( int j = 0 ; j < n2; j++)
{
// Mark chk as false and
// break the loop
if (T.charAt(j) != S.charAt(i + j))
{
chk = false ;
break ;
}
}
// If chk is true
if (chk)
{
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1 ));
// Update the last to i + 1
last = i + 1 ;
}
}
// Print the answer
System.out.println(ans);
} // Driver code
public static void main (String[] args)
{
String S = "dabc" , T = "ab" ;
// Function Call
findOccurrences(S, T);
}
} // This code is contributed by AnkThon |
# Python3 program for the above approach # Function to count the substrings of # containing another given # as a sub def findOccurrences(S, T):
# Store length of S
n1 = len (S)
# Store length of T
n2 = len (T)
# Store the required count of
# substrings
ans = 0
# Store the starting index of
# last occurrence of T in S
last = 0
# Iterate in range [0, n1-n2]
for i in range (n1 - n2 + 1 ):
# Check if subfrom i
# to i + n2 is equal to T
chk = True
# Check if subfrom i
# to i + n2 is equal to T
for j in range (n2):
# Mark chk as false and
# break the loop
if (T[j] ! = S[i + j]):
chk = False
break
# If chk is true
if (chk):
# Add (i + 1 - last) *
# (n1 - (i + n2 - 1))
# to answer
ans + = (i + 1 - last) * (n1 - (i + n2 - 1 ))
# Update the last to i + 1
last = i + 1
# Print the answer
print (ans)
# Driver code if __name__ = = '__main__' :
S,T = "dabc" , "ab"
# Function Call
findOccurrences(S, T)
# This code is contributed by mohit kumar 29 |
// C# program for the above approach using System;
class GFG
{ // Function to count the substrings of // string containing another given // string as a substring static void findOccurrences(String S, String T)
{ // Store length of string S
int n1 = S.Length;
// Store length of string T
int n2 = T.Length;
// Store the required count of
// substrings
int ans = 0;
// Store the starting index of
// last occurrence of T in S
int last = 0;
// Iterate in range [0, n1-n2]
for ( int i = 0; i <= n1 - n2; i++)
{
// Check if substring from i
// to i + n2 is equal to T
bool chk = true ;
// Check if substring from i
// to i + n2 is equal to T
for ( int j = 0; j < n2; j++)
{
// Mark chk as false and
// break the loop
if (T[j] != S[i + j])
{
chk = false ;
break ;
}
}
// If chk is true
if (chk)
{
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
Console.WriteLine(ans);
} // Driver code
public static void Main(String[] args)
{
String S = "dabc" , T = "ab" ;
// Function Call
findOccurrences(S, T);
}
} // This code is contributed by 29AjayKumar |
<script> // JavaScript program for above approach // Function to count the substrings of // string containing another given // string as a substring function findOccurrences(S, T)
{ // Store length of string S
let n1 = S.length;
// Store length of string T
let n2 = T.length;
// Store the required count of
// substrings
let ans = 0;
// Store the starting index of
// last occurrence of T in S
let last = 0;
// Iterate in range [0, n1-n2]
for (let i = 0; i <= n1 - n2; i++)
{
// Check if substring from i
// to i + n2 is equal to T
let chk = true ;
// Check if substring from i
// to i + n2 is equal to T
for (let j = 0; j < n2; j++)
{
// Mark chk as false and
// break the loop
if (T[j] != S[i + j])
{
chk = false ;
break ;
}
}
// If chk is true
if (chk)
{
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
document.write(ans);
} // Driver Code let S = "dabc" , T = "ab" ;
// Function Call
findOccurrences(S, T);
</script> |
4
Time Complexity: O(N*M) since two nested loops are used where N and M are the lengths of given strings.
Auxiliary Space: O(1) since no extra array is used the space occupied by the algorithm is constant.