📌  相关文章
📜  为每个查询选择任意长度的K个相等长度的子字符串的方式数量

📅  最后修改于: 2021-06-25 14:24:16             🧑  作者: Mango

给定一个字符串strQ查询。每个查询包含一个整数K。任务是找到为每个查询选择任意长度的K个相等子字符串的方法数量。请注意,K个子串的集合必须是唯一的。

例子:

方法:可以按照以下步骤解决问题并在尽可能短的时间内回答每个查询。

  • 生成一个字符串的所有子字符串,并使用哈希计算每个唯一子字符串的出现次数。
  • 对于每个查询,答案将选择出现超过K次(例如X)的每个字符串的K个子字符串。答案将是X \choose K
  • 可以通过预先计算二项式系数来降低每个查询的时间复杂度

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define maxlen 100
  
// Function to generate all the sub-strings
void generateSubStrings(string s, unordered_map& mpp)
{
  
    // Length of the string
    int l = s.length();
  
    // Generate all sub-strings
    for (int i = 0; i < l; i++) {
        string temp = "";
        for (int j = i; j < l; j++) {
            temp += s[j];
  
            // Count the occurrence of
            // every sub-string
            mpp[temp] += 1;
        }
    }
}
  
// Compute the Binomial Coefficient
void binomialCoeff(int C[maxlen][maxlen])
{
    int i, j;
  
    // Calculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 100; j++) {
  
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously
            // stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
}
  
// Function to return the result for a query
int answerQuery(unordered_map& mpp,
                int C[maxlen][maxlen], int k)
{
    int ans = 0;
  
    // Iterate for every
    // unique sub-string
    for (auto it : mpp) {
  
        // Count the combinations
        if (it.second >= k)
            ans += C[it.second][k];
    }
  
    return ans;
}
  
// Driver code
int main()
{
    string s = "aabaab";
  
    // Get all the sub-strings
    // Store the occurrence of
    // all the sub-strings
    unordered_map mpp;
    generateSubStrings(s, mpp);
  
    // Pre-computation
    int C[maxlen][maxlen];
    memset(C, 0, sizeof C);
    binomialCoeff(C);
  
    // Queries
    int queries[] = { 2, 3, 4 };
    int q = sizeof(queries) / sizeof(queries[0]);
  
    // Perform queries
    for (int i = 0; i < q; i++)
        cout << answerQuery(mpp, C, queries[i]) << endl;
  
    return 0;
}


Java
// Java implementation of the approach 
import java.util.HashMap;
  
class GFG 
{
    static int maxlen = 100;
  
    // Function to generate all the sub-strings
    public static void generateSubStrings(
                       String s, HashMap mpp) 
    {
  
        // Length of the string
        int l = s.length();
  
        // Generate all sub-strings
        for (int i = 0; i < l; i++)
        {
            String temp = "";
            for (int j = i; j < l; j++) 
            {
                temp += s.charAt(j);
  
                // Count the occurrence of
                // every sub-string
                if (mpp.containsKey(temp)) 
                {
                    int x = mpp.get(temp);
                    mpp.put(temp, ++x);
                } 
                else
                    mpp.put(temp, 1);
            }
        }
    }
  
    // Compute the Binomial Coefficient
    public static void binomialCoeff(int[][] C) 
    {
        int i, j;
  
        // Calculate value of Binomial Coefficient
        // in bottom up manner
        for (i = 1; i < 100; i++) 
        {
            for (j = 0; j < 100; j++)
            {
  
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
  
                // Calculate value using previously
                // stored values
                else
                    C[i][j] = C[i - 1][j - 1] + 
                              C[i - 1][j];
            }
        }
    }
  
    // Function to return the result for a query
    public static int answerQuery(HashMap mpp, 
                                      int[][] C, int k)
    {
        int ans = 0;
  
        // Iterate for every
        // unique sub-string
        for (HashMap.Entry entry : mpp.entrySet()) 
        {
  
            // Count the combinations
            if (entry.getValue() >= k)
                ans += C[entry.getValue()][k];
        }
        return ans;
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        String s = "aabaab";
  
        // Get all the sub-strings
        // Store the occurrence of
        // all the sub-strings
        HashMap mpp = new HashMap<>();
        generateSubStrings(s, mpp);
  
        // Pre-computation
        int[][] C = new int[maxlen][maxlen];
        binomialCoeff(C);
  
        // Queries
        int[] queries = { 2, 3, 4 };
        int q = queries.length;
  
        // Perform queries
        for (int i = 0; i < q; i++)
            System.out.println(answerQuery(mpp, C, 
                                     queries[i]));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of the approach 
from collections import defaultdict
  
maxlen = 100
  
# Function to generate all the sub-strings 
def generateSubStrings(s, mpp): 
  
    # Length of the string 
    l = len(s) 
  
    # Generate all sub-strings 
    for i in range(0, l): 
        temp = "" 
        for j in range(i, l): 
            temp += s[j] 
  
            # Count the occurrence of 
            # every sub-string 
            mpp[temp] += 1
  
# Compute the Binomial Coefficient 
def binomialCoeff(C): 
  
    # Calculate value of Binomial 
    # Coefficient in bottom up manner 
    for i in range(0, 100): 
        for j in range(0, 100): 
  
            # Base Cases 
            if j == 0 or j == i: 
                C[i][j] = 1
  
            # Calculate value using previously 
            # stored values 
            else:
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j] 
  
# Function to return the result for a query 
def answerQuery(mpp, C, k): 
  
    ans = 0
    # Iterate for every 
    # unique sub-string 
    for it in mpp: 
  
        # Count the combinations 
        if mpp[it] >= k: 
            ans += C[mpp[it]][k] 
  
    return ans 
  
# Driver code 
if __name__ == "__main__":
      
    s = "aabaab"
      
    # Get all the sub-strings 
    # Store the occurrence of 
    # all the sub-strings 
    mpp = defaultdict(lambda:0)
    generateSubStrings(s, mpp) 
  
    # Pre-computation 
    C = [[0 for i in range(maxlen)] 
            for j in range(maxlen)]
    binomialCoeff(C) 
  
    # Queries 
    queries = [2, 3, 4] 
    q = len(queries) 
  
    # Perform queries 
    for i in range(0, q): 
        print(answerQuery(mpp, C, queries[i]))
          
# This code is contributed by Rituraj Jain


C#
// C# code to print level order 
// traversal in sorted order
using System;
using System.Collections.Generic;
  
class GFG 
{ 
    static int maxlen = 100;
  
    // Function to generate all the sub-strings
    public static void generateSubStrings(String s, 
                               Dictionary mpp) 
    {
  
        // Length of the string
        int l = s.Length;
  
        // Generate all sub-strings
        for (int i = 0; i < l; i++)
        {
            String temp = "";
            for (int j = i; j < l; j++) 
            {
                temp += s[j];
  
                // Count the occurrence of
                // every sub-string
                if (mpp.ContainsKey(temp)) 
                {
                    mpp[temp] = ++mpp[temp];
                } 
                else
                    mpp.Add(temp, 1);
            }
        }
    }
  
    // Compute the Binomial Coefficient
    public static void binomialCoeff(int[,] C) 
    {
        int i, j;
  
        // Calculate value of Binomial Coefficient
        // in bottom up manner
        for (i = 1; i < 100; i++) 
        {
            for (j = 0; j < 100; j++)
            {
  
                // Base Cases
                if (j == 0 || j == i)
                    C[i, j] = 1;
  
                // Calculate value using previously
                // stored values
                else
                    C[i, j] = C[i - 1, j - 1] + 
                              C[i - 1, j];
            }
        }
    }
  
    // Function to return the result for a query
    public static int answerQuery(Dictionary mpp, 
                                           int[,] C, int k)
    {
        int ans = 0;
  
        // Iterate for every
        // unique sub-string
        foreach(KeyValuePair entry in mpp) 
        {
  
            // Count the combinations
            if (entry.Value >= k)
                ans += C[entry.Value, k];
        }
        return ans;
    }
  
    // Driver code
    public static void Main(String[] args) 
    {
        String s = "aabaab";
  
        // Get all the sub-strings
        // Store the occurrence of
        // all the sub-strings
        Dictionary mpp = new Dictionary();
        generateSubStrings(s, mpp);
  
        // Pre-computation
        int[,] C = new int[maxlen, maxlen];
        binomialCoeff(C);
  
        // Queries
        int[] queries = { 2, 3, 4 };
        int q = queries.Length;
  
        // Perform queries
        for (int i = 0; i < q; i++)
            Console.WriteLine(answerQuery(mpp, C, 
                                    queries[i]));
    }
}
  
// This code is contributed by 29AjayKumar


输出:
10
4
1