Count of Distinct Substrings occurring consecutively in a given String

Given a string str, the task is to find the number of distinct substrings that are placed consecutively in the given string.
Examples: 

Input: str = “geeksgeeksforgeeks” 
Output:
Explanation: 
geeksgeeksforgeeks -> {“geeks”} 
geeksgeeksforgeeks -> {“e”} 
Only one consecutive occurrence of “e” is considered. 
Therefore two distinct substrings {“geeks”, “e”} occur consecutively in the string. 
Therefore, the answer is 2.

Input: s = “geeksforgeeks” 
Output:
Explanation: 
geeksgeeksforgeeks -> {“e”, “e”} 
Only one substring {“e”} occurs consecutively in the string. 
 

Naive Approach: 
The simplest approach is to generate all possible substrings of the given string, and for each substring, find the count of substrings in the given occurring consecutively in the string. Finally, print the count. 
Time Complexity: O(N3)
Auxiliary Space: O(N)

Efficient Approach: 
To optimize the above approach, the idea is to use Dynamic Programming
Follow the steps below to solve the problem:

  1. If the length of the string does not exceed 1, then it is not possible to find any such consecutively placed similar substrings. So return 0 as the count.
  2. Otherwise, initialize a memoization table dp[] of dimensions (N+1 * N+1) which is initialized to 0.
  3. Initialize an unordered_set to store the distinct substrings placed consecutively.
  4. Iterate from the end of the string.
  5. While traversing the string if any repeating character is found, then dp[i][j] will be determined considering the previously computed dp value i.e., count of identical substrings up to dp[i+1][j+1] characters and including the current character.
  6. If the character is not similar then, dp[i][j] will be filled with 0.
  7. Similar substrings are consecutively placed together without any other characters and they will be the same for at most (j – i) characters. Hence, for valid substrings, dp[i][j] value must be greater than (j – i). Store those substrings in unordered_set which appears the maximum number of times consecutively.
  8. Finally, return the size of the unordered_set as the count of distinct substrings placed consecutively.

Below is the implementation of the above approach:



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to count the distinct substrings
// placed consecutively in the given string
int distinctSimilarSubstrings(string str)
{
    // Length of the string
    int n = str.size();
  
    // If length of the string
    // does not exceed 1
    if (n <= 1) {
        return 0;
    }
  
    // Initialize a DP-table
    vector<vector<int> > dp(
        n + 1, vector<int>(n + 1, 0));
  
    // Stores the distinct substring
    unordered_set<string> substrings;
  
    // Iterate from end of the string
    for (int j = n - 1; j >= 0; j--) {
  
        // Iterate backward until
        // dp table is all computed
        for (int i = j - 1; i >= 0; i--) {
  
            // If character at i-th index is
            // same as character at j-th index
            if (str[i] == str[j]) {
  
                // Update dp[i][j] based on
                // previously computed value
                dp[i][j] = dp[i + 1][j + 1] + 1;
            }
  
            // Otherwise
            else {
  
                dp[i][j] = 0;
            }
  
            // Condition for consecutively
            // placed similar substring
            if (dp[i][j] >= j - i) {
  
                substrings.insert(
                    str.substr(i, j - i));
            }
        }
    }
  
    // Return the count
    return substrings.size();
}
  
// Driver Code
int main()
{
    string str = "geeksgeeksforgeeks";
  
    cout << distinctSimilarSubstrings(str);
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement 
# the above approach 
  
# Function to count the distinct substrings
# placed consecutively in the given string
def distinctSimilarSubstrings(str):
  
    # Length of the string
    n = len(str)
  
    # If length of the string
    # does not exceed 1
    if(n <= 1):
        return 0
  
    # Initialize a DP-table
    dp = [[0 for x in range(n + 1)]
             for y in range(n + 1)]
  
    # Stores the distinct substring
    substrings = set()
  
    # Iterate from end of the string
    for j in range(n - 1, -1, -1):
  
        # Iterate backward until
        # dp table is all computed
        for i in range(j - 1, -1, -1):
  
            # If character at i-th index is
            # same as character at j-th index
            if(str[i] == str[j]):
  
                # Update dp[i][j] based on
                # previously computed value
                dp[i][j] = dp[i + 1][j + 1] + 1
  
            # Otherwise
            else:
                dp[i][j] = 0
  
            # Condition for consecutively
            # placed similar substring
            if(dp[i][j] >= j - i):
                substrings.add(str[i : j - i])
  
    # Return the count 
    return len(substrings)
  
# Driver Code
str = "geeksgeeksforgeeks"
  
# Function call
print(distinctSimilarSubstrings(str))
  
# This code is contributed by Shivam Singh

chevron_right


Output: 

2

Time Complexity: O(N) 
Auxiliary Space: O(N)
 

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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 Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : SHIVAMSINGH67