Open in App
Not now

# Generate a Number in Decreasing order of Frequencies of characters of a given String

• Difficulty Level : Medium
• Last Updated : 31 Mar, 2023

Given a string Str of length N, consisting of lowercase alphabets, the task is to generate a number in decreasing order of the frequency of characters in the given string. If two characters have the same frequency, the character with a smaller ASCII value appears first. Numbers assigned to characters {a, b, …., y, z} are {1, 2, …., 25, 26} respectively.

Note: For characters having values greater than 9 assigned to them, take its modulo 10.

Examples:

Input: N = 6, Str = “aaabbd”
Output: 124
Explanation:
Given characters and their respective frequencies are:

• a = 3
• b = 2
• d = 1

Since the number needs to be generated in increasing order of their frequencies, the final generated number is 124.

Input: N = 6, Str = “akkzzz”
Output: 611
Explanation:
Given characters and their respective frequencies are:

• a = 1
• k = 2
• z = 3

For z, value to assigned = 26
Hence, the corresponding digit assigned = 26 % 10 = 6
For k, value to assigned = 11
Hence, the corresponding digit assigned = 11 % 10 = 1
Since the number needs to be generated in increasing order of their frequencies, the final generated number is 611

Approach:
Follow the steps below to solve the problem:

1. Initialize a Map and store the frequencies of each character.
2. Traverse the Map and insert all {Character, Frequency} pairs in a vector of pair.
3. Sort this vector in a way such that the pair with higher frequency appears first and among pairs having the same frequency, those with smaller ASCII value come first.
4. Traverse this vector and find the digit corresponding to each character.
5. Print the final number generated.

Below is the implementation of the above approach:

## C++

 // C++ Program to implement // the above approach #include using namespace std;   // Custom comparator for sorting bool comp(pair& p1,           pair& p2) {       // If frequency is same     if (p1.second == p2.second)           // Character with lower ASCII         // value appears first         return p1.first < p2.first;       // Otherwise character with higher     // frequency appears first     return p1.second > p2.second; }   // Function to sort map accordingly string sort(map& m) {       // Declaring vector of pairs     vector > a;       // Output string to store the result     string out;       // Traversing map and pushing     // pairs to vector     for (auto x : m) {           a.push_back({ x.first, x.second });     }       // Using custom comparator     sort(a.begin(), a.end(), comp);       // Traversing the Vector     for (auto x : a) {           // Get the possible digit         // from assigned value         int k = x.first - 'a' + 1;           // Ensures k does not exceed 9         k = k % 10;           // Append each digit         out = out + to_string(k);     }       // Returning final result     return out; }   // Function to generate and return // the required number string formString(string s) {     // Stores the frequencies     map mp;       for (int i = 0; i < s.length(); i++)         mp[s[i]]++;       // Sort map in required order     string res = sort(mp);       // Return the final result     return res; }   // Driver Code int main() {     int N = 4;       string Str = "akkzzz";       cout << formString(Str);       return 0; }

## Java

 // java Program to implement // the above approach import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class FormString {     static class Pair implements Comparable {         char first;         int second;           Pair(char first, int second) {             this.first = first;             this.second = second;         }         // custom comparator for sorting         @Override         public int compareTo(Pair o) {              // is frequency same             if (this.second == o.second) {                 // Character with lower ASCII                 // value appears first                 return this.first - o.first;             }             // Otherwise character with higher             // frequency appears first             return o.second - this.second;         }     } // Function to sort map accordingly     static String sort(Map map) {         // Declaring vector of pairs         List list = new ArrayList<>();         // Traversing map and pushing         // pairs to List Integerface         for (Map.Entry entry : map.entrySet()) {             list.add(new Pair(entry.getKey(), entry.getValue()));         }         // Sorting using Collections sort         Collections.sort(list);         StringBuilder sb = new StringBuilder();         for (Pair pair : list) {              // Get the possible digit             // from assigned value and             // Ensuring k does not exceed 9             int k = (pair.first - 'a' + 1) % 10;             // append each digit             sb.append(k);         }         // Returning final result         return sb.toString();     }       static String formString(String s) {         // map are used to store freq         Map map = new HashMap<>();         for (int i = 0; i < s.length(); i++) {             map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);         }         // sort map and return         return sort(map);     }    // Main function (Driver code)     public static void main(String[] args) {         String Str = "akkzzz";         System.out.println(formString(Str));     } }

## Python3

 # Python3 Program to implement # the above approach   # Function to sort map # accordingly def sort(m):       # Declaring vector     # of pairs     a = {}       # Output string to     # store the result     out = ""       # Traversing map and     # pushing pairs to vector     for x in m:         a[x] = []           a[x].append(m[x])       # Character with lower ASCII     # value appears first     a = dict(sorted(a.items(),                   key = lambda x : x[0]))       # Character with higher     # frequency appears first     a = dict(sorted(a.items(),                     reverse = True,                     key = lambda x : x[1]))       # Traversing the Vector     for x in a:           # Get the possible digit         # from assigned value         k = ord(x[0]) - ord('a') + 1           # Ensures k does         # not exceed 9         k = k % 10           # Append each digit         out = out + str(k)       # Returning final result     return out   # Function to generate and return # the required number def formString(s):       # Stores the frequencies     mp = {}     for i in range(len(s)):         if s[i] in mp:             mp[s[i]] += 1         else:             mp[s[i]] = 1       # Sort map in     # required order     res = sort(mp)       # Return the     # final result     return res   # Driver Code N = 4 Str = "akkzzz" print(formString(Str))   # This code is contributed by avanitrachhadiya2155



## C#

 // C# program to implement the above approach  using System; using System.Collections.Generic; using System.Linq;   public class Program {     // Function to sort dictionary     // accordingly     static string SortDictionary(Dictionary dict)     {         // Declaring dictionary of pairs         Dictionary sortedDict = new Dictionary();           // Traversing dictionary and         // pushing pairs to dictionary of pairs         foreach (var pair in dict)         {             sortedDict.Add(pair.Key, pair.Value);         }           // Sorting dictionary by value in descending order         sortedDict = sortedDict.OrderByDescending(pair => pair.Value)                              .ThenBy(pair => pair.Key)                              .ToDictionary(pair => pair.Key, pair => pair.Value);           // Building output string         string output = "";         foreach (var pair in sortedDict)         {             // Get the possible digit             // from assigned value and             // ensuring k does not exceed 9             int k = (pair.Key - 'a' + 1) % 10;               // Append each digit             output += k.ToString();         }           // Returning final result         return output;     }       // Function to generate and return     // the required number     static string GetFormedString(string str)     {         // Stores the frequencies         Dictionary freq = new Dictionary();         foreach (char c in str)         {             if (freq.ContainsKey(c))             {                 freq++;             }             else             {                 freq.Add(c, 1);             }         }           // Sort dictionary in         // required order         string formedStr = SortDictionary(freq);           // Return the         // final result         return formedStr;     }       // Main function (Driver code)     public static void Main(string[] args)     {         string str = "akkzzz";         Console.WriteLine(GetFormedString(str));     } }   // Contributed by adiyasha4x71

Output

611

Time Complexity: O(NlogN)
Auxiliary Space: O(N)

Approach 2:

1. Initialize an array count of size 26 to store the frequency of each character in the string.
2. Traverse the string and update the frequency count of each character in the array.
3. Traverse the count array and create a vector of pairs where each pair consists of a character and its frequency.
4. Sort the vector of pairs in decreasing order of frequency. For pairs with the same frequency, sort them in increasing order of ASCII value.
5. Traverse the sorted vector and generate the digit corresponding to each character. Append each digit to the result string.
6. Return the result string.

Below is the implementation of the above approach:

## C++

 #include using namespace std;   string formString(string s) {     // Step 1: Initialize count array     int count[26] = {0};     for (int i = 0; i < s.length(); i++) {         count[s[i] - 'a']++;     }       // Step 2: Create vector of pairs     vector> v;     for (int i = 0; i < 26; i++) {         if (count[i] > 0) {             v.push_back(make_pair('a' + i, count[i]));         }     }       // Step 3: Sort vector of pairs     sort(v.begin(), v.end(), [](pair& p1, pair& p2) {         if (p1.second == p2.second) {             return p1.first < p2.first;         }         return p1.second > p2.second;     });       // Step 4: Generate result string     string res;     for (auto& p : v) {         int digit = (p.first - 'a' + 1) % 10;         res += to_string(digit);     }       // Step 5: Return result string     return res; }   int main() {     int N = 6;     string Str = "akkzzz";     cout << formString(Str); // Output: 611     return 0; }

## Python3

 def form_string(s):     # Step 1: Initialize count array     count = [0]*26     for i in range(len(s)):         count[ord(s[i]) - ord('a')] += 1       # Step 2: Create list of tuples     v = []     for i in range(26):         if count[i] > 0:             v.append((chr(i + ord('a')), count[i]))       # Step 3: Sort list of tuples     v.sort(key=lambda x: (-x[1], x[0]))       # Step 4: Generate result string     res = ""     for p in v:         digit = (ord(p[0]) - ord('a') + 1) % 10         res += str(digit)       # Step 5: Return result string     return res s = "akkzzz"   print(form_string(s))  # Output: 611

Output

611

Time Complexity: O(nlogn)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up
Related Articles