# Minimum addition/removal of characters to be done to make frequency of each character prime

Given a string S of length N, the task is to find the minimum operations required to make the frequency of every distinct character prime. The frequency of a character can be increased or decreased by 1 in a single operation.
Examples:

Input: S = “abba”
Output:
Explanation: There are two characters in the string S and the frequency of ‘a’ is 2 which is prime. The frequency of ‘b’ is 2 which is also a prime number.Hence no operations are required for this case.

Input: S = “aaaaaaaaa”
Output:
Explanation: The frequency of ‘a’ in the string is 9. Either remove 2 a’s from the string or add 2 a’s in the string to make the frequency of ‘a’ prime. Thus minimum number of operations needed is 2.

Naive Approach:
Find the frequency of each character in the string. Let the frequency be X. Find the prime number greater than X and less than X. Compare the difference between X and the two prime numbers found and choose the closest prime number. Add the difference between the closest prime number and X to the number of operations. Thus the minimum number of operations will be obtained. It is an inefficient approach as the lower and upper bound to find the prime number is not known.

Efficient Approach :

1. Use the sieve algorithm to find all the prime numbers up to N and store them in an array.
2. Find out the nearest lower prime number for all the numbers from i = 1 to N and store the difference between i and its nearest lower prime number in an array say arr1[].
3. Find out the nearest higher prime number for all the numbers from i = 1 to N and store the difference between i and its nearest higher prime number in an array say arr2[].
4. Traverse the string and find the frequency of all the distinct characters in the string and use an unordered_map to save the frequencies of these distinct characters.
5. Let the frequency of any distinct character be X then find out the distance between X and the nearest prime number from the arrays arr1[] and arr2[].
6. Choose the distance which is lesser between the two and add this distance to the number of operations.
7. Do this for all the distinct characters and print the number of operations finally.

Below is the implementation of the above approach:

## C++

 `// C++ code for the above approach`   `#include ` `#include ` `#include ` `using` `namespace` `std;`   `// using the seive to find` `// the prime factors.` `void` `spf_array(``int` `spf[], ``int` `d)` `{` `    ``spf = 1;` `    ``int` `i = 0;`   `    ``// setting every number` `    ``// as prime number initailly` `    ``for` `(i = 2; i <= d; i++) {` `        ``spf[i] = i;` `    ``}`   `    ``// removing the even numbers as` `    ``// they cannot be prime except 2` `    ``for` `(i = 2; i <= d; i = i + 2) {` `        ``spf[i] = 2;` `    ``}`   `    ``for` `(i = 3; i * i <= d; i++) {` `        ``// if they are prime` `        ``if` `(spf[i] == i) {` `            ``int` `j;`   `            ``// iterating the loop for` `            ``// prime and eliminate all` `            ``// the multiples of three` `            ``for` `(j = i * i; j <= d; j = j + i) {` `                ``if` `(spf[j] == j) {` `                    ``spf[j] = i;` `                ``}` `            ``}` `        ``}` `    ``}` `}`   `// function to find the closest` `// prime number of every` `// number upto N (size of the string)` `void` `closest_prime_spf(``int` `spf[],` `                       ``int` `cspf[], ``int` `d)` `{` `    ``// for the base case` `    ``cspf = 1;`   `    ``int` `i = 0, j = 0, k = 0;`   `    ``// iterating to find the` `    ``// distance from the` `    ``// lesser nearest prime` `    ``for` `(i = 2; i < d; i++) {` `        ``if` `(spf[i] != i) {` `            ``cspf[i] = ``abs``(i - k);` `        ``}` `        ``else` `{` `            ``cspf[i] = -1;` `            ``k = i;` `        ``}` `    ``}`   `    ``// iterating to find the` `    ``// distance from the` `    ``// lesser nearest prime` `    ``for` `(i = d - 1; i >= 2; i--) {` `        ``if` `(spf[i] != i) {` `            ``if` `(cspf[i] > ``abs``(k - i)) {` `                ``cspf[i] = ``abs``(k - i);` `            ``}` `        ``}` `        ``else` `{` `            ``k = i;` `        ``}` `    ``}` `}`   `// function to find the` `// minimum operation` `int` `minimum_operation(``int` `cspf[],` `                      ``string s)` `{`   `    ``// created map to find the` `    ``// frequency of distinct characters` `    ``unordered_map<``char``, ``int``> m;`   `    ``// variable to iterate and` `    ``// holding the minimum operation` `    ``int` `i = 0, k = 0;`   `    ``// loop for calculation frequency` `    ``for` `(i = 0; i < s.length(); i++) {` `        ``m[s[i]] = m[s[i]] + 1;` `    ``}`   `    ``// iterate over frequency` `    ``// if we not get a chcarter` `    ``// frequency prime` `    ``// then we find the closest` `    ``// prime and add` `    ``for` `(``auto` `x : m) {` `        ``int` `h = x.second;` `        ``if` `(cspf[h] != -1) {` `            ``k = k + cspf[h];` `        ``}` `    ``}` `    ``return` `k;` `}`   `// Function to find the` `// minimum number of operations` `void` `minOper(string s)` `{`   `    ``int` `spf[s.length() + 1];` `    ``int` `cspf[s.length() + 1];`   `    ``// function called to create` `    ``// the spf` `    ``spf_array(spf, s.length() + 1);`   `    ``// function called to` `    ``// create the cspf` `    ``closest_prime_spf(spf, cspf,` `                      ``s.length() + 1);`   `    ``cout << minimum_operation(cspf, s)` `         ``<< endl;` `}`   `// Driver Code` `int` `main()` `{` `    ``// input string` `    ``string s = ``"aaaaaaaaabbcccccc"``;`   `    ``minOper(s);`   `    ``return` `0;` `}`

## Java

 `// Java code for the above approach` `import` `java.util.*;`   `class` `GFG{`   `// Using the seive to find` `// the prime factors.` `static` `void` `spf_array(``int` `spf[], ``int` `d)` `{` `    ``spf[``1``] = ``1``;` `    ``int` `i = ``0``;`   `    ``// Setting every number` `    ``// as prime number initailly` `    ``for``(i = ``2``; i < d; i++)` `    ``{` `        ``spf[i] = i;` `    ``}`   `    ``// Removing the even numbers as` `    ``// they cannot be prime except 2` `    ``for``(i = ``2``; i < d; i = i + ``2``)` `    ``{` `        ``spf[i] = ``2``;` `    ``}`   `    ``for``(i = ``3``; i * i <= d; i++)` `    ``{` `        `  `        ``// If they are prime` `        ``if` `(spf[i] == i)` `        ``{` `            ``int` `j;`   `            ``// Iterating the loop for` `            ``// prime and eliminate all` `            ``// the multiples of three` `            ``for``(j = i * i; j < d; j = j + i) ` `            ``{` `                ``if` `(spf[j] == j) ` `                ``{` `                    ``spf[j] = i;` `                ``}` `            ``}` `        ``}` `    ``}` `}`   `// Function to find the closest` `// prime number of every` `// number upto N (size of the String)` `static` `void` `closest_prime_spf(``int` `spf[],` `                              ``int` `cspf[],` `                              ``int` `d)` `{` `    `  `    ``// For the base case` `    ``cspf[``1``] = ``1``;`   `    ``int` `i = ``0``, k = ``0``;`   `    ``// Iterating to find the` `    ``// distance from the` `    ``// lesser nearest prime` `    ``for``(i = ``2``; i < d; i++)` `    ``{` `        ``if` `(spf[i] != i)` `        ``{` `            ``cspf[i] = Math.abs(i - k);` `        ``}` `        ``else` `        ``{` `            ``cspf[i] = -``1``;` `            ``k = i;` `        ``}` `    ``}`   `    ``// Iterating to find the` `    ``// distance from the` `    ``// lesser nearest prime` `    ``for``(i = d - ``1``; i >= ``2``; i--) ` `    ``{` `        ``if` `(spf[i] != i)` `        ``{` `            ``if` `(cspf[i] > Math.abs(k - i)) ` `            ``{` `                ``cspf[i] = Math.abs(k - i);` `            ``}` `        ``}` `        ``else` `        ``{` `            ``k = i;` `        ``}` `    ``}` `}`   `// Function to find the` `// minimum operation` `static` `int` `minimum_operation(``int` `cspf[],` `                             ``String s)` `{` `    `  `    ``// Created map to find the` `    ``// frequency of distinct characters` `    ``HashMap m = ``new` `HashMap<>();`   `    ``// Variable to iterate and` `    ``// holding the minimum operation` `    ``int` `i = ``0``, k = ``0``;`   `    ``// Loop for calculation frequency` `    ``for``(i = ``0``; i < s.length(); i++) ` `    ``{` `        ``if` `(m.containsKey(s.charAt(i)))` `            ``m.put(s.charAt(i),` `            ``m.get(s.charAt(i)) + ``1``);` `        ``else` `            ``m.put(s.charAt(i), ``1``);` `    ``}`   `    ``// Iterate over frequency` `    ``// if we not get a chcarter` `    ``// frequency prime then we` `    ``// find the closest` `    ``// prime and add` `    ``for``(Map.Entry x : m.entrySet())` `    ``{` `        ``int` `h = x.getValue();` `        ``if` `(cspf[h] != -``1``) ` `        ``{` `            ``k = k + cspf[h];` `        ``}` `    ``}` `    ``return` `k;` `}`   `// Function to find the` `// minimum number of operations` `static` `void` `minOper(String s)` `{` `    ``int` `[]spf = ``new` `int``[s.length() + ``1``];` `    ``int` `[]cspf = ``new` `int``[s.length() + ``1``];`   `    ``// Function called to create` `    ``// the spf` `    ``spf_array(spf, s.length() + ``1``);`   `    ``// Function called to` `    ``// create the cspf` `    ``closest_prime_spf(spf, cspf,` `                      ``s.length() + ``1``);`   `    ``System.out.print(minimum_operation(cspf, s) + ``"\n"``);` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    `  `    ``// Input String` `    ``String s = ``"aaaaaaaaabbcccccc"``;`   `    ``minOper(s);` `}` `}`   `// This code is contributed by Amit Katiyar`

## C#

 `// C# code for the ` `// above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{`   `// Using the seive to find` `// the prime factors.` `static` `void` `spf_array(``int` `[]spf, ` `                      ``int` `d)` `{` `  ``spf = 1;` `  ``int` `i = 0;`   `  ``// Setting every number` `  ``// as prime number initailly` `  ``for``(i = 2; i < d; i++)` `  ``{` `    ``spf[i] = i;` `  ``}`   `  ``// Removing the even numbers as` `  ``// they cannot be prime except 2` `  ``for``(i = 2; i < d; i = i + 2)` `  ``{` `    ``spf[i] = 2;` `  ``}`   `  ``for``(i = 3; i * i <= d; i++)` `  ``{` `    ``// If they are prime` `    ``if` `(spf[i] == i)` `    ``{` `      ``int` `j;`   `      ``// Iterating the loop for` `      ``// prime and eliminate all` `      ``// the multiples of three` `      ``for``(j = i * i; j < d; j = j + i) ` `      ``{` `        ``if` `(spf[j] == j) ` `        ``{` `          ``spf[j] = i;` `        ``}` `      ``}` `    ``}` `  ``}` `}`   `// Function to find the closest` `// prime number of every` `// number upto N (size of the String)` `static` `void` `closest_prime_spf(``int` `[]spf,` `                              ``int` `[]cspf,` `                              ``int` `d)` `{    ` `  ``// For the base case` `  ``cspf = 1;`   `  ``int` `i = 0, k = 0;`   `  ``// Iterating to find the` `  ``// distance from the` `  ``// lesser nearest prime` `  ``for``(i = 2; i < d; i++)` `  ``{` `    ``if` `(spf[i] != i)` `    ``{` `      ``cspf[i] = Math.Abs(i - k);` `    ``}` `    ``else` `    ``{` `      ``cspf[i] = -1;` `      ``k = i;` `    ``}` `  ``}`   `  ``// Iterating to find the` `  ``// distance from the` `  ``// lesser nearest prime` `  ``for``(i = d - 1; i >= 2; i--) ` `  ``{` `    ``if` `(spf[i] != i)` `    ``{` `      ``if` `(cspf[i] > Math.Abs(k - i)) ` `      ``{` `        ``cspf[i] = Math.Abs(k - i);` `      ``}` `    ``}` `    ``else` `    ``{` `      ``k = i;` `    ``}` `  ``}` `}`   `// Function to find the` `// minimum operation` `static` `int` `minimum_operation(``int` `[]cspf,` `                             ``String s)` `{`   `  ``// Created map to find the` `  ``// frequency of distinct characters` `  ``Dictionary<``char``, ` `             ``int``> m = ``new` `Dictionary<``char``, ` `                                     ``int``>();` `  `  `  ``// Variable to iterate and` `  ``// holding the minimum operation` `  ``int` `i = 0, k = 0;`   `  ``// Loop for calculation ` `  ``// frequency` `  ``for``(i = 0; i < s.Length; i++) ` `  ``{` `    ``if` `(m.ContainsKey(s[i]))` `      ``m[s[i]] = m[s[i]] + 1;` `    ``else` `      ``m.Add(s[i], 1);` `  ``}`   `  ``// Iterate over frequency` `  ``// if we not get a chcarter` `  ``// frequency prime then we` `  ``// find the closest` `  ``// prime and add` `  ``foreach``(KeyValuePair<``char``,` `                       ``int``> x ``in` `m)` `  ``{` `    ``int` `h = x.Value;` `    ``if` `(cspf[h] != -1) ` `    ``{` `      ``k = k + cspf[h];` `    ``}` `  ``}` `  ``return` `k;` `}`   `// Function to find the` `// minimum number of operations` `static` `void` `minOper(String s)` `{` `  ``int` `[]spf = ``new` `int``[s.Length + 1];` `  ``int` `[]cspf = ``new` `int``[s.Length + 1];`   `  ``// Function called to create` `  ``// the spf` `  ``spf_array(spf, s.Length + 1);`   `  ``// Function called to` `  ``// create the cspf` `  ``closest_prime_spf(spf, cspf,` `                    ``s.Length + 1);`   `  ``Console.Write(minimum_operation(` `                ``cspf, s) + ``"\n"``);` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args)` `{` `  ``// Input String` `  ``String s = ``"aaaaaaaaabbcccccc"``;`   `  ``minOper(s);` `}` `}`   `// This code is contributed by shikhasingrajput`

Output:

```3

```

Time complexity: O(N * log(log(N)))
Auxiliary Space complexity: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Article Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.