📌  相关文章
📜  计算给定长度的不同子字符串的数量

📅  最后修改于: 2021-04-23 15:36:43             🧑  作者: Mango

给定一个长度为N的字符串S,该字符串由小写英语字母和一个整数’l’组成,找到给定字符串的长度为’l’的不同子字符串的数量。
例子:

天真的方法:
一种简单的方法是找到所有可能的子字符串,找到它们的哈希值,并找到不同的子字符串的数量。
时间复杂度: O(l * N)

高效的方法:
我们将使用滚动哈希算法解决此问题。

  • 查找长度为“ l”的第一个子字符串的哈希值。
    可以评估为(s [0] -97)* x ^(l-1)+(s [1] -97)* x ^(1-2)…(s [l-1] -97)。让我们称其为“ H 1 ”。
  • 使用此哈希值,我们将生成下一个哈希值:
    H 2 =(H 1- (s [0] -97)* x ^(l-1)* x +(s [l] -97)。以这种方式生成所有子串的哈希
    并以无序的方式推动它们。
  • 计算集合中不同值的数量。

下面是上述方法的实现:

C++
// C++ implementation of above approach
#include 
#define x 26
#define mod 3001
using namespace std;
  
// Function to find the required count
int CntSubstr(string s, int l)
{
    // Variable to the hash
    int hash = 0;
  
    // Finding hash of substring
    // (0, l-1) using random number x
    for (int i = 0; i < l; i++) {
        hash = (hash * x + (s[i] - 97)) % mod;
    }
  
    // Computing x^(l-1)
    int pow_l = 1;
    for (int i = 0; i < l - 1; i++)
        pow_l = (pow_l * x) % mod;
  
    // Unordered set to add hash values
    unordered_set result;
    result.insert(hash);
  
    // Generating all possible hash values
    for (int i = l; i < s.size(); i++) {
        hash = ((hash - pow_l * (s[i - l] - 97)
              + 2 * mod) * x + (s[i] - 97)) % mod;
        result.insert(hash);
    }
  
    // Print the result
    cout << result.size() << endl;
}
  
// Driver Code
int main()
{
    string s = "abcba";
  
    int l = 2;
  
    CntSubstr(s, l);
  
    return 0;
}


Java
// Java implementation of above approach
import java.util.*;
  
class GFG
{
  
    static int x = 26;
    static int mod = 3001;
  
    // Function to find the required count
    static void CntSubstr(char[] s, int l)
    {
        // Variable to the hash
        int hash = 0;
  
        // Finding hash of substring
        // (0, l-1) using random number x
        for (int i = 0; i < l; i++) 
        {
            hash = (hash * x + (s[i] - 97)) % mod;
        }
  
        // Computing x^(l-1)
        int pow_l = 1;
        for (int i = 0; i < l - 1; i++) 
        {
            pow_l = (pow_l * x) % mod;
        }
  
        // Unordered set to add hash values
        HashSet result = new HashSet();
        result.add(hash);
  
        // Generating all possible hash values
        for (int i = l; i < s.length; i++) 
        {
            hash = ((hash - pow_l * (s[i - l] - 97)
                    + 2 * mod) * x + (s[i] - 97)) % mod;
            result.add(hash);
        }
  
        // Print the result
        System.out.println(result.size());
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String s = "abcba";
  
        int l = 2;
  
        CntSubstr(s.toCharArray(), l);
    }
}
  
// This code contributed by Rajput-Ji


C#
// C# implementation of the approach
using System;
using System.Collections.Generic; 
  
class GFG
{
  
    static int x = 26;
    static int mod = 3001;
  
    // Function to find the required count
    static void CntSubstr(char[] s, int l)
    {
        // Variable to the hash
        int hash = 0;
  
        // Finding hash of substring
        // (0, l-1) using random number x
        for (int i = 0; i < l; i++) 
        {
            hash = (hash * x + (s[i] - 97)) % mod;
        }
  
        // Computing x^(l-1)
        int pow_l = 1;
        for (int i = 0; i < l - 1; i++) 
        {
            pow_l = (pow_l * x) % mod;
        }
  
        // Unordered set to add hash values
        HashSet result = new HashSet();
        result.Add(hash);
  
        // Generating all possible hash values
        for (int i = l; i < s.Length; i++) 
        {
            hash = ((hash - pow_l * (s[i - l] - 97)
                    + 2 * mod) * x + (s[i] - 97)) % mod;
            result.Add(hash);
        }
  
        // Print the result
        Console.WriteLine(result.Count);
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        String s = "abcba";
  
        int l = 2;
  
        CntSubstr(s.ToCharArray(), l);
    }
}
  
/* This code contributed by PrinciRaj1992 */


Python3
# Python3 implementation of above approach 
x = 26
mod = 3001
  
# Function to find the required count 
def CntSubstr(s, l) : 
  
    # Variable to the hash 
    hash = 0; 
  
    # Finding hash of substring 
    # (0, l-1) using random number x 
    for i in range(l) :
        hash = (hash * x + (ord(s[i]) - 97)) % mod; 
  
    # Computing x^(l-1) 
    pow_l = 1; 
    for i in range(l-1) : 
        pow_l = (pow_l * x) % mod; 
  
    # Unordered set to add hash values 
    result = set(); 
    result.add(hash); 
  
    # Generating all possible hash values 
    for i in range(l,len(s)) :
        hash = ((hash - pow_l * (ord(s[i - l]) - 97) 
            + 2 * mod) * x + (ord(s[i]) - 97)) % mod; 
          
        result.add(hash); 
  
    # Print the result 
    print(len(result)) ; 
  
  
# Driver Code 
if __name__ == "__main__" : 
  
    s = "abcba"; 
  
    l = 2; 
  
    CntSubstr(s, l); 
      
# This code is contributed by AnkitRai01


输出:
4

时间复杂度: O(N)