Open In App

K most occurring strings

Given an array arr[] of N strings and an integer K, the task is to print K strings which occurred the most number of times in the arr[]. If two or more strings have the same frequency then print the lexicographically smallest string.
Note: The value of K is always less than or equal to the number of distinct elements in the array.

Examples: 

Input: str[] = {“geeks”, “geeksforgeeks”, “geeks”, “article”}, K = 1 
Output: “geeks” 
Explanation: 
“geeks” –> 2 
“geeksforgeeks” –> 1 
“article” –> 1 
Hence, the most occurring string is “geeks”

Input: str[] = {“car”, “bus”, “car”, “bike”, “car”, “bus”, “bike”, “cycle”}, K = 2 
Output : “car”, “bus” 
Explanation: 
“car” –> 3 
“bus” –> 2 
“bike” –> 2 
“cycle” –> 1 
string “car” has highest frequency, string “bus” and “bike” both have second highest frequency, but string “bus” is lexicographically small because it has shorter length.

 

Approach:

  1. Count the frequency of each string in the array and store it in a HashMap where the string is the key and frequency as the value.
  2. Now, sort these keys according to their frequencies in ascending order, this is done to keep keys with the least frequencies at the top.
  3. The strings with equal frequencies are prioritized alphabetically, i.e., the string which is alphabetically greater has a higher priority.
  4. Delete the top N – K key-value pairs from the HashMap. By doing this the container is left with K keys with the highest frequencies, in reverse order.
  5. Print the strings stored in the HashMap.

Below is the implementation of the above approach:
 




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns list of K
// most frequent strings
map<string, int> Freq;
class compare {
  public:
  bool operator()(string& a, string& b)
  {
    if (a == b) {
      return Freq[a] > Freq[b];
    }
    return a > b;
  }
};
vector<string> frequentWords(vector<string> arr, int K)
{
 
  // Hash map to store the frequency
  // of each string
  map<string, int> Freq;
 
  // Set the default frequency of
  // each string 0
  for (auto word : arr) {
    Freq[word]++;
  }
 
  // Using a priority queue to store
  // the strings in accordance of the
  // frequency and alphabetical order
  // (if frequency is equal)
 
  // Lambda expression is used set the
  // priority, if frequencies are not
  // equal than the string with greater
  // frequency is returned else the
  // string which is lexically smaller
  // is returned
  priority_queue<string, vector<string>, compare> Order;
 
  // Traverse the HashMap
  for (auto it : Freq) {
    Order.push(it.first);
 
    // Remove top (N - K) elements
    if (Order.size() > K) {
      Order.pop();
    }
  }
 
  // Order queue has K most frequent
  // strings in a reverse order
  vector<string> ans;
  while (Order.size()) {
    ans.push_back(Order.top());
    Order.pop();
  }
 
  // Reverse the ArrayList so as
  // to get in the desired order
  reverse(ans.begin(), ans.end());
 
  return ans;
}
 
// Driver Code
int main()
{
  int N = 3, K = 2;
 
  // Given array
  vector<string> arr{ "car", "bus", "car" };
 
  // Function Call
  vector<string> ans = frequentWords(arr, K);
 
  // Print the K most occurring strings
  for (auto it : ans) {
    cout << it << endl;
  }
}
 
// This code is contributed by garg28harsh.




// Java program for the above approach
import java.util.*;
 
class FrequentWords {
 
    // Function that returns list of K
    // most frequent strings
    public static ArrayList<String>
    frequentWords(ArrayList<String> arr, int K)
    {
 
        // Hash map to store the frequency
        // of each string
        HashMap<String, Integer> Freq
            = new HashMap<>();
 
        // Set the default frequency of
        // each string 0
        for (String word : arr) {
            Freq.put(word,
                     Freq.getOrDefault(word, 0)
                         + 1);
        }
 
        // Using a priority queue to store
        // the strings in accordance of the
        // frequency and alphabetical order
        // (if frequency is equal)
 
        // Lambda expression is used set the
        // priority, if frequencies are not
        // equal than the string with greater
        // frequency is returned else the
        // string which is lexically smaller
        // is returned
        PriorityQueue<String> Order
            = new PriorityQueue<>(
                (a, b)
                    -> (Freq.get(a) != Freq.get(b))
                           ? Freq.get(a) - Freq.get(b)
                           : b.compareTo(a));
 
        // Traverse the HashMap
        for (String word : Freq.keySet()) {
            Order.offer(word);
 
            // Remove top (N - K) elements
            if (Order.size() > K) {
                Order.poll();
            }
        }
 
        // Order queue has K most frequent
        // strings in a reverse order
        ArrayList<String> ans
            = new ArrayList<>();
 
        while (!Order.isEmpty()) {
            ans.add(Order.poll());
        }
 
        // Reverse the ArrayList so as
        // to get in the desired order
        Collections.reverse(ans);
 
        return ans;
    }
 
    // Driver Code
    public static void
        main(String[] args)
    {
        int N = 3, K = 2;
 
        // Given array
        ArrayList<String> arr
            = new ArrayList<String>();
        arr.add("car");
        arr.add("bus");
        arr.add("car");
 
        // Function Call
        ArrayList<String> ans
            = frequentWords(arr, K);
 
        // Print the K most occurring strings
        for (String word : ans) {
            System.out.println(word + " ");
        }
    }
}




using System;
using System.Collections.Generic;
using System.Linq;
 
// Class to store the solution
class Solution
{
    // Function to return the list of K most frequent words
    public static IList<string> frequentWords(IList<string> arr, int K)
    {
        // Dictionary to store the frequency of each word
        Dictionary<string, int> Freq = new Dictionary<string, int>();
 
        // Loop through the given list to update the frequency of each word
        foreach (string word in arr)
        {
            if (Freq.ContainsKey(word))
            {
                // Increase the frequency if the word already exists in the dictionary
                Freq[word]++;
            }
            else
            {
                // Add the word to the dictionary and set its frequency to 1
                Freq[word] = 1;
            }
        }
 
        // SortedSet to store the words in accordance of the frequency
        SortedSet<string> Order = new SortedSet<string>(Comparer<string>.Create((a, b) =>
        {
            // Compare the frequency of two words
            int freqCompare = Freq[b].CompareTo(Freq[a]);
 
            // If the frequencies are equal, compare the words lexically
            if (freqCompare == 0)
            {
                return string.Compare(a, b, StringComparison.Ordinal);
            }
            return freqCompare;
        }));
 
        // Loop through the keys of the dictionary to add them to the SortedSet
        foreach (string word in Freq.Keys)
        {
            Order.Add(word);
 
            // Remove the last element if the size of the SortedSet exceeds K
            if (Order.Count > K)
            {
                Order.Remove(Order.Last());
            }
        }
 
        // Convert the SortedSet to a list and return it
        return Order.ToList();
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int N = 3, K = 2;
        List<string> arr = new List<string>() { "car", "bus", "car" };
 
        // Call the function to get the list of K most frequent words
        List<string> ans = frequentWords(arr, K).ToList();
 
        // Loop through the list and print each word
        foreach (string word in ans)
        {
            Console.WriteLine(word);
        }
    }
}
//This code is contributed by rudra1807raj




// Javascript program for the above approach
 
// Function that returns list of K
// most frequent strings
function frequentWords(arr, K)
{
    // Hash map to store the frequency
    // of each string
    var Freq = new Map();
     
    // Set the default frequency of
    // each string 0
    for (var word of arr) {
        Freq.set(word, Freq.has(word)?Freq.get(word):0);
    }
     
    // Using a priority queue to store
    // the strings in accordance of the
    // frequency and alphabetical order
    // (if frequency is equal)
    // Lambda expression is used set the
    // priority, if frequencies are not
    // equal than the string with greater
    // frequency is returned else the
    // string which is lexically smaller
    // is returned
    var Order = [];
 
    // Traverse the HashMap
    for (var word of [...Freq.keys()]) {
        Order.push(word);
        // Remove top (N - K) elements
        if (Order.length > K) {
            Order.pop();
        }
    }
    // Order queue has K most frequent
    // strings in a reverse order
    var ans = [];
    Order.sort((a,b)=>a[0]-b[0]);
    while (Order.length!=0) {
        ans.push(Order[Order.length-1])
        Order.pop();
    }
    // Reverse the ArrayList so as
    // to get in the desired order
    ans.reverse();
    return ans;
}
 
// Driver Code
var N = 3, K = 2;
 
// Given array
var arr = [];
arr.push("car");
arr.push("bus");
arr.push("car");
// Function Call
 
var ans = frequentWords(arr, K);
 
// Print the K most occurring strings
for (var word of ans) {
    console.log(word);
}
 
// This code is contributed by noob2000.




#Python code
#importing libraries
import collections
from collections import Counter
from queue import PriorityQueue
 
#Function that returns list of K most frequent strings
def frequentWords(arr, K):
    # Hash map to store the frequency
    # of each string
    Freq = Counter(arr)
     
    # Using a priority queue to store
    # the strings in accordance of the
    # frequency and alphabetical order
    # (if frequency is equal)
    Order = PriorityQueue()
 
    # Traverse the HashMap
    for word in Freq:
        Order.put((-Freq[word], word))
     
        # Remove top (N - K) elements
        if Order.qsize() > K:
            Order.get()
 
    # Order queue has K most frequent
    # strings in a reverse order
    ans = []
 
    while not Order.empty():
        ans.append(Order.get()[1])
 
    # Reverse the ArrayList so as
    # to get in the desired order
    ans.reverse()
 
    return ans
 
# Driver Code
if __name__ == "__main__":
    N = 3
    K = 2
 
    # Given array
    arr = ["car", "bus", "car"]
 
    # Function Call
    ans = frequentWords(arr, K)[::-1]
 
    # Print the K most occurring strings
    print(*ans, sep="\n")

 
 

Output: 
car 
bus

 

Time Complexity: O(N*log2N)
Auxiliary Space: O(N) 

 


Article Tags :