Generate a Number in Decreasing order of Frequencies of characters of a given String
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:
- Initialize a Map and store the frequencies of each character.
- Traverse the Map and insert all {Character, Frequency} pairs in a vector of pair.
- 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.
- Traverse this vector and find the digit corresponding to each character.
- Print the final number generated.
Below is the implementation of the above approach:
C++
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std; // Custom comparator for sorting bool comp(pair< char , int >& p1, pair< char , int >& 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< char , int >& m) { // Declaring vector of pairs vector<pair< char , int > > 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< char , int > 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<Pair> { 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<Character, Integer> map) { // Declaring vector of pairs List<Pair> list = new ArrayList<>(); // Traversing map and pushing // pairs to List Integerface for (Map.Entry<Character, Integer> 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<Character, Integer> 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 |
Javascript
<script> // JavaScript Program to implement // the above approach // Custom comparator for sorting function comp(p1,p2) { // If frequency is same if (p1[1] == p2[1]) // Character with lower ASCII // value appears first return p2.charCodeAt(0) - p1.charCodeAt(0); // Otherwise character with higher // frequency appears first return p2[1] - p1[1]; } // Function to sort map accordingly function sort(m) { // Declaring vector of pairs let a = []; // Output string to store the result let out= "" ; // Traversing map and pushing // pairs to vector for (let [x,y] of m) { a.push([ x, y ]); } // Using custom comparator a.sort(comp); // Traversing the Vector for (let x of a) { // Get the possible digit // from assigned value let k = (x[0].charCodeAt(0) - 97 + 1)%10; // Append each digit out += k.toString(); } // Returning final result return out; } // Function to generate and return // the required number function formString(s) { // Stores the frequencies let mp = new Map(); for (let i = 0; i < s.length; i++){ if (mp.has(s[i])){ mp.set(s[i],mp.get(s[i])+1); } else { mp.set(s[i],1); } } // Sort map in required order let res = sort(mp); // Return the final result return res; } // Driver Code let N = 4; let Str = "akkzzz" ; document.write(formString(Str), "</br>" ); // This code is contributed by shinjanpatra </script> |
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< char , int > dict) { // Declaring dictionary of pairs Dictionary< char , int > sortedDict = new Dictionary< char , int >(); // 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< char , int > freq = new Dictionary< char , int >(); 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 |
611
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Approach 2:
- Initialize an array count of size 26 to store the frequency of each character in the string.
- Traverse the string and update the frequency count of each character in the array.
- Traverse the count array and create a vector of pairs where each pair consists of a character and its frequency.
- Sort the vector of pairs in decreasing order of frequency. For pairs with the same frequency, sort them in increasing order of ASCII value.
- Traverse the sorted vector and generate the digit corresponding to each character. Append each digit to the result string.
- Return the result string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h> 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<pair< char , int >> 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< char , int >& p1, pair< char , int >& 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; } |
Java
import java.util.*; public class Main { // Pair class implementation static class Pair<K, V> { public K key; public V value; public Pair(K key, V value) { this .key = key; this .value = value; } public K getKey() { return key; } public V getValue() { return value; } } public static String formString(String s) { // Step 1: Initialize count array int [] count = new int [ 26 ]; for ( int i = 0 ; i < s.length(); i++) { count[s.charAt(i) - 'a' ]++; } // Step 2: Create list of pairs List<Pair<Character, Integer>> v = new ArrayList<>(); for ( int i = 0 ; i < 26 ; i++) { if (count[i] > 0 ) { v.add( new Pair<>(( char )( 'a' + i), count[i])); } } // Step 3: Sort list of pairs Collections.sort(v, new Comparator<Pair<Character, Integer>>() { @Override public int compare(Pair<Character, Integer> p1, Pair<Character, Integer> p2) { if (p1.getValue().equals(p2.getValue())) { return Character.compare(p1.getKey(), p2.getKey()); } return Integer.compare(p2.getValue(), p1.getValue()); } }); // Step 4: Generate result string StringBuilder res = new StringBuilder(); for (Pair<Character, Integer> p : v) { int digit = (p.getKey() - 'a' + 1 ) % 10 ; res.append(digit); } // Step 5: Return result string return res.toString(); } public static void main(String[] args) { int N = 6 ; String Str = "akkzzz" ; System.out.println(formString(Str)); // Output: 611 } } |
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 |
Javascript
// Javascript code addition function formString(s) { // Step 1: Initialize count array const count = new Array(26).fill(0); for (let i = 0; i < s.length; i++) { count[s.charCodeAt(i) - 97]++; } // Step 2: Create list of pairs const v = []; for (let i = 0; i < 26; i++) { if (count[i] > 0) { v.push([String.fromCharCode(i + 97), count[i]]); } } // Step 3: Sort list of pairs v.sort((p1, p2) => { if (p1[1] === p2[1]) { return p1[0].localeCompare(p2[0]); } return p2[1] - p1[1]; }); // Step 4: Generate result string let res = '' ; for (let i = 0; i < v.length; i++) { const digit = (v[i][0].charCodeAt(0) - 97 + 1) % 10; res += digit.toString(); } // Step 5: Return result string return res; } const N = 6; const Str = 'akkzzz' ; console.log(formString(Str)); // Output: 611 // The code is contributed by Arushi Goel. |
611
Time Complexity: O(nlogn)
Auxiliary Space: O(1)
Please Login to comment...