📌  相关文章
📜  给定字符串中连续出现的不同子字符串的计数

📅  最后修改于: 2021-10-27 07:55:47             🧑  作者: Mango

给定一个字符串str ,任务是找到在给定字符串连续放置的不同子字符串的数量。

例子:

天真的方法:
最简单的方法是生成给定字符串 的所有可能的子串,并且对于每个子串,找到在字符串连续出现的给定子串的计数。最后,打印计数。

时间复杂度: O(N 3 )
辅助空间: O(N)

有效的方法:
为了优化上述方法,想法是使用动态规划。
请按照以下步骤解决问题:

  1. 如果字符串的长度不超过 1 ,则不可能找到任何此类连续放置的相似子字符串。所以返回 0作为计数
  2. 否则,初始化一个维度为(N+1 * N+1)的记忆表dp[] ,它被初始化为0
  3. 初始化unordered_set以存储连续放置的不同子字符串。
  4. 从字符串的末尾开始迭代。
  5. 在遍历字符串,如果发现任何重复字符,则dp[i][j]将根据先前计算的 dp 值确定,即,最多dp[i+1][j+1] 个字符的相同子串的计数,包括当前字符。
  6. 如果字符不相似,则dp[i][j]将填充为 0。
  7. 相似的子串被连续放置在一起,没有任何其他字符,它们至多(j – i) 个字符的。因此,对于有效的子字符串, dp[i][j] 值必须大于 (j – i) 。将这些子字符串存储在连续出现次数最多的unordered_set中。
  8. 最后,返回unordered_set的大小作为连续放置的不同子字符串的计数。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
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 > dp(
        n + 1, vector(n + 1, 0));
 
    // Stores the distinct substring
    unordered_set 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;
}


Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.ArrayList;
 
class GFG{
 
// Function to count the distinct substrings
// placed consecutively in the given string    
static int distinctSimilarSubstrings(String str)
{
     
    // Length of the string
    int n = str.length();
     
    // If length of the string
    // does not exceed 1
    if (n <= 1)
        return 0;
         
    // Initialize a DP-table
    long dp[][] = new long[n + 1][n + 1];
     
    // Declaring ArrayList to store strings
    ArrayList list = new ArrayList();
 
    // 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.charAt(i) == str.charAt(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)
            {
                list.add(str.substring(j - i, i));
            }
        }
    }
     
    // Return the count
    return list.size();
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "geeksforgeeks";
     
    System.out.println(distinctSimilarSubstrings(str));
}
}
 
// This code is contributed by user_00


Python3
# 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


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Function to count the distinct substrings
    // placed consecutively in the given string    
    static int distinctSimilarSubstrings(string str)
    {
          
        // Length of the string
        int n = str.Length;
          
        // If length of the string
        // does not exceed 1
        if (n <= 1)
            return 0;
              
        // Initialize a DP-table
        long[,] dp = new long[n + 1, n + 1];
          
        // Declaring ArrayList to store strings
        List list = new List();
      
        // 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)
                {
                    list.Add(str.Substring(i, j - i));
                }
            }
        }
          
        // Return the count
        return list.Count;
    }
 
  // Driver code
  static void Main()
  {
    string str = "geeksforgeeks";    
    Console.WriteLine(distinctSimilarSubstrings(str));
  }
}
 
// This code is contributed by divyesh072019


Javascript


输出:
2

时间复杂度: O(N)
辅助空间: O(N)