📜  计算特殊字符与给定字符串的子字符串长度之比的总和

📅  最后修改于: 2021-05-14 01:01:25             🧑  作者: Mango

给定一个字符串str和一个特殊字符数组specialArray [] ,任务是为给定字符串的所有可能子字符串找到特殊字符计数与子字符串长度之比的总和。

例子:

方法:
请按照以下步骤解决问题:

  • 对于从1到N的每个可能的子字符串长度,找到长度为x的每个子字符串中特殊字符的计数,然后将count与x的比率加到答案中。
  • 要找到在一定的时间每个子特殊字符计数,创建的使用关系特殊字符计数的前缀和数组:
  • 计算索引[i,j]中子字符串中特殊字符的数量,由以下关系式给出:

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
const int N = 1e5 + 5;
 
// Stores frequency of special
// characters in the array
vector prefix(N, 0);
 
// Stores prefix sum
vector sum(N, 0);
 
// Function to check whether a character
// is special or not
bool isSpecial(char c,
               vector& special)
{
    for (auto& i : special)
 
        // If current character
        // is special
        if (i == c)
            return true;
 
    // Otherwise
    return false;
}
 
// Function to find sum of ratio of
// count of special characters and
// length of substrings
double countRatio(string& s,
                  vector& special)
{
 
    int n = s.length();
    for (int i = 0; i < n; i++) {
 
        // Calculate the prefix sum of
        // special nodes
        prefix[i] = int(isSpecial(s[i],
                                  special));
        if (i > 0)
            prefix[i] += prefix[i - 1];
    }
 
    for (int i = 0; i < n; i++) {
 
        // Generate prefix sum array
        sum[i] = prefix[i];
        if (i > 0)
            sum[i] += sum[i - 1];
    }
 
    double ans = 0;
    for (int i = 1; i <= n; i++) {
 
        // Calculate ratio for substring
        int count = sum[n - 1]
                    - (i > 1 ? sum[i - 2] : 0);
        count
            -= (i < n ? sum[n - i - 1] : 0);
 
        ans += double(count) / double(i);
    }
 
    return ans;
}
 
// Driver Code;
int main()
{
    string s = "abcd";
    vector special = { 'b', 'c' };
 
    double ans = countRatio(s, special);
 
    cout << fixed << setprecision(6)
         << ans << endl;
 
    return 0;
}


Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
 
static int N = 1000000 + 5;
 
// Stores frequency of special
// characters in the array
static int []prefix = new int[N];
   
// Stores prefix sum
static int []sum = new int[N];
 
// Function to check
// whether a character
// is special or not
static int isSpecial(char c,
                     char[] special)
{
  for (char i : special)
 
    // If current character
    // is special
    if (i == c)
      return 1;
 
  // Otherwise
  return 0;
}
 
// Function to find sum of ratio of
// count of special characters and
// length of subStrings
static  double countRatio(char []s,
                          char[] special)
{
  int n = s.length;
  for (int i = 0; i < n; i++)
  {
    // Calculate the prefix sum of
    // special nodes
    prefix[i] = (isSpecial(s[i],
                 special));
    if (i > 0)
      prefix[i] += prefix[i - 1];
  }
 
  for (int i = 0; i < n; i++)
  {
    // Generate prefix sum array
    sum[i] = prefix[i];
    if (i > 0)
      sum[i] += sum[i - 1];
  }
 
  double ans = 0;
  for (int i = 1; i <= n; i++)
  {
    // Calculate ratio for subString
    int count = sum[n - 1] - (i > 1 ?
                sum[i - 2] : 0);
    count -= (i < n ?
              sum[n - i - 1] : 0);
    ans += (double)count / (double)i;
  }
 
  return ans;
}
 
// Driver Code;
public static void main(String[] args)
{
  String s = "abcd";
  char[] special = {'b', 'c'};
  double ans = countRatio(s.toCharArray(),
                          special);
  System.out.format("%.6f",ans);
}
}
 
// This code is contributed by gauravrajput1


Python3
# Python3 program to implement
# the above approach
N = 100005
 
# Stores frequency of special
# characters in the array
prefix = [0] * N
 
# Stores prefix sum
sum = [0] * N
 
# Function to check whether a character
# is special or not
def isSpecial(c, special):
 
    for i in special:
 
        # If current character
        # is special
        if (i == c):
            return True
 
    # Otherwise
    return False
 
# Function to find sum of ratio of
# count of special characters and
# length of substrings
def countRatio(s, special):
 
    n = len(s)
    for i in range(n):
 
        # Calculate the prefix sum of
        # special nodes
        prefix[i] = int(isSpecial(s[i],
                                  special))
        if (i > 0):
            prefix[i] += prefix[i - 1]
 
    for i in range(n):
 
        # Generate prefix sum array
        sum[i] = prefix[i]
        if (i > 0):
            sum[i] += sum[i - 1]
 
    ans = 0
    for i in range(1, n + 1):
 
        # Calculate ratio for substring
        if i > 1:
            count = sum[n - 1]- sum[i - 2]
        else:
            count = sum[n - 1]
        if i < n:
            count -= sum[n - i - 1]
 
        ans += count / i
     
    return ans
 
# Driver Code
if __name__ == "__main__":
     
    s = "abcd"
    special = [ 'b', 'c' ]
 
    ans = countRatio(s, special)
 
    print('%.6f' % ans)
 
# This code is contributed by chitranayal


C#
// C# Program to implement
// the above approach
using System;
 
class GFG{
 
static int N = 1000000 + 5;
 
// Stores frequency of special
// characters in the array
static int []prefix = new int[N];
   
// Stores prefix sum
static int []sum = new int[N];
 
// Function to check
// whether a character
// is special or not
static int isSpecial(char c,
                     char[] special)
{
  foreach(char i in special)
     
    // If current character
    // is special
    if (i == c)
      return 1;
 
  // Otherwise
  return 0;
}
 
// Function to find sum of ratio of
// count of special characters and
// length of subStrings
static  double countRatio(char []s,
                          char[] special)
{
  int n = s.Length;
  for(int i = 0; i < n; i++)
  {
     
    // Calculate the prefix sum of
    // special nodes
    prefix[i] = (isSpecial(s[i],
                 special));
    if (i > 0)
      prefix[i] += prefix[i - 1];
  }
 
  for(int i = 0; i < n; i++)
  {
     
    // Generate prefix sum array
    sum[i] = prefix[i];
     
    if (i > 0)
      sum[i] += sum[i - 1];
  }
 
  double ans = 0;
  for(int i = 1; i <= n; i++)
  {
     
    // Calculate ratio for subString
    int count = sum[n - 1] - (i > 1 ?
                sum[i - 2] : 0);
    count -= (i < n ?
              sum[n - i - 1] : 0);
    ans += (double)count / (double)i;
  }
  return ans;
}
 
// Driver Code;
public static void Main(String[] args)
{
  String s = "abcd";
  char[] special = {'b', 'c'};
  double ans = countRatio(s.ToCharArray(),
                          special);
   
  Console.WriteLine("{0:F6}", ans);
}
}
 
// This code is contributed by Princi Singh


输出:
5.833333

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