Calculate Sum of ratio of special characters to length of substrings of the given string
Last Updated :
06 Oct, 2022
Given a string str and an array of special characters, specialArray[], the task is to find the sum of the ratio of the count of special characters to the length of the substring for all possible substring of the given string.
Ratio of count of special characters in a substring to the length of substrings of the given string is given by
f(i, j) = \frac{\displaystyle\sum_{k = i}^{j} special(s_k)}{j - i + 1}
Sum of the ratios calculated above is given by
\displaystyle\sum_{1<=i<=j<=|s|}^{} f(i, j)
Examples:
Input: str = "abcdabc", specialArray[] = {'a', 'b', 'c', 'd'}
Output: 28.00000
Explanation:
Length of string = 7
Count of all possible substrings = (7 * (8 + 1)) / 2 = 28
Since, all the characters of the string are included in specialArray[], ratio of count of special characters to the length of substring for every substring will always be 1.
Hence, the sum of ratio = Number of substrings * 1 = 28.
Input: str = "abcd", specialArray[] = {'b', 'c'}
Output: 5.83333
Approach:
Follow the steps below to solve the problem:
- For every possible length of substrings from 1 to N, find the count of special characters in every substring of length x and add the ratio of count and x to the answer.
- To find the count of special characters in each substring in constant time, create a prefix sum array of the count of special characters using the relation:
prefix[i] = prefix[i - 1] + special(s[i]);
- Calculate the count of special characters in a substring within the indices [i, j] is given by the relation:
prefix[j - 1] - prefix[i - 1]
Therefore, the ratio of the count of special characters to the length of substring,
f(i, j) = (prefix[j - 1] - prefix[i - 1])/(j - i + 1)
Below is the implementation of the above approach:
C++
// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
// Stores frequency of special
// characters in the array
vector<int> prefix(N, 0);
// Stores prefix sum
vector<int> sum(N, 0);
// Function to check whether a character
// is special or not
bool isSpecial(char c,
vector<char>& 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<char>& 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<char> 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
JavaScript
<script>
// Javascript program to implement
// the above approach
var N = 1000005;
// Stores frequency of special
// characters in the array
var prefix = Array(N).fill(0);
// Stores prefix sum
var sum = Array(N).fill(0);
// Function to check whether a character
// is special or not
function isSpecial(c, special)
{
var ans = false;
special.forEach(i => {
// If current character
// is special
if (i == c)
ans =true;
});
// Otherwise
return ans;
}
// Function to find sum of ratio of
// count of special characters and
// length of substrings
function countRatio(s, special)
{
var n = s.length;
for(var 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(var i = 0; i < n; i++)
{
// Generate prefix sum array
sum[i] = prefix[i];
if (i > 0)
sum[i] += sum[i - 1];
}
var ans = 0;
for(var i = 1; i <= n; i++)
{
// Calculate ratio for substring
var count = sum[n - 1] -
((i > 1) ? sum[i - 2] : 0);
count -= ((i < n) ? sum[n - i - 1] : 0);
ans += ((count) / (i));
}
return ans;
}
// Driver Code;
var s = "abcd";
var special = [ 'b', 'c' ];
var ans = countRatio(s.split(''), special);
document.write( ans.toFixed(6));
// This code is contributed by itsok
</script>
Time Complexity: O(N)
Space Complexity: O(N)
Similar Reads
Lengths of maximized partitions of a string such that each character of the string appears in one substring Given string str of lowercase alphabets, split the given string into as many substrings as possible such that each character from the given string appears in a single substring. The task is to print the length of all such partitions. Examples: Input: str = "acbbcc"Output: 1 5Explanation:Possible par
8 min read
Print all Substrings of length n possible from the given String Given a string str and an integer N, the task is to print all possible sub-strings of length N. Examples: Input: str = âgeeksforgeeksâ, N = 3Output: gee eek eks ksf sfo for org rge gee eek eksExplanations: All possible sub-strings of length 3 are âgeeâ, âeekâ, âeksâ, âksfâ, âsfoâ, âforâ, âorgâ, ârge
8 min read
Count the sum of count of distinct characters present in all Substrings Given a string S consisting of lowercase English letters of size N where (1 <= N <= 105), the task is to print the sum of the count of distinct characters N where (1 <= N <= 105)in all the substrings. Examples: Input: str = "abbca"Output: 28Explanation: The following are the substrings o
8 min read
Count odd length Substrings with median same as Kth character of String Given a string S of size N, the task is to find the number of substrings of odd lengths that have a median equal to the Kth character of the string. Examples: Input: S = "ecadgg", K = 4Output: 4Explanation: Character at 4th position in string is 'd'. Then there are 4 odd length substrings with 'd' a
11 min read
Count number of substrings of a string consisting of same characters Given a string. The task is to find out the number of substrings consisting of the same characters. Examples: Input: abba Output: 5 The desired substrings are {a}, {b}, {b}, {a}, {bb} Input: bbbcbb Output: 10 Approach: It is known for a string of length n, there are a total of n*(n+1)/2 number of su
6 min read
Length of smallest substring to be replaced to make frequency of each character as N/3 Given a string str of length N (divisible by 3) consisting of atmost three distinct characters, the task is to find the length of the smallest substring whose characters can be replaced so that each character occurs exactly N/3 times. Examples: Input: str = "ABB"Output: 1Explanation: One optimal way
9 min read