Open In App

Sort an array of strings based on the frequency of good words in them

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given a set of product reviews (R) by different customers and a string S containing good words separated by a _, the task is to sort the reviews in decreasing order of their goodness value. Goodness Value is defined by the number of good words present in that review. 

Examples:

Input: S = “geeks_for_geeks_is_great”, R = {“geeks_are_geeks”, “geeks_dont_lose”, “geeks_for_geeks_is_love”} 
Output: geeks for geeks is love geeks are geeks geeks dont lose 

Input: S = “cool_wifi_ice”, R = {“water_is_cool”, “cold_ice_drink”, “cool_wifi_speed”} 
Output: cool wifi speed water is cool cold ice drink

Naive approach: Insert all the good words in an unordered_set and then iterate through each word of each sentence of the reviews array and keep a count of the good words by checking if this word is present in that set of good words. We then use a stable sorting algorithm and sort the array R according to the count of good words in each review present in R. It’s clear that the time complexity of this method is greater than O(N * NlogN) . Efficient approach: Make a Trie of all the good words and check the goodness of each word in a review using the trie.

  1. Insert all the good words in a trie.
  2. For each review, calculate the number of good words in it by checking whether a given word exists in the trie or not.

Below is the implementation of the above approach: 

CPP14




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define MAX 26
 
// Comparator function for sorting
bool cmp(const pair<int, int>& a, const pair<int, int>& b)
{
 
    // Compare the number of good words
    if (a.F == b.F)
        return a.S < b.S;
    return a.F > b.F;
}
 
// Structure of s Trie node
struct node {
    bool exist;
    node* arr[MAX];
    node(bool bul = false)
    {
        exist = bul;
        for (int i = 0; i < MAX; i++)
            arr[i] = NULL;
    }
};
 
// Function to add a string to the trie
void add(string s, node* trie)
{
    // Add a node to the trie
    int n = s.size();
    for (int i = 0; i < n; i++) {
 
        // If trie doesn't already contain
        // the current node then create one
        if (trie->arr[s[i] - 'a'] == NULL)
            trie->arr[s[i] - 'a'] = new node();
 
        trie = trie->arr[s[i] - 'a'];
    }
    trie->exist = true;
    return;
}
 
// Function that returns true if
// the trie contains the string s
bool search(string s, node* trie)
{
    // Search for a node in the trie
    for (int i = 0; i < s.size(); i++) {
        if (trie->arr[s[i] - 'a'] == NULL)
            return false;
 
        trie = trie->arr[s[i] - 'a'];
    }
    return trie->exist;
}
 
// Function to replace every '_' with a
// white space in the given string
void convert(string& str)
{
    // Convert '_' to spaces
    for (int i = 0; i < str.size(); i++)
        if (str[i] == '_')
            str[i] = ' ';
    return;
}
 
// Function to sort the array based on good words
void sortArr(string good, vector<string>& review)
{
 
    // Extract all the good words which
    // are '_' separated
    convert(good);
    node* trie = new node();
    string word;
    stringstream ss;
    ss << good;
 
    // Building the entire trie by stringstreaming
    // the 'good words' string
    while (ss >> word)
        add(word, trie);
    int k, n = review.size();
 
    // To store the number of good words
    // and the string index pairs
    vector<pair<int, int> > rating(n);
    for (int i = 0; i < n; i++) {
        convert(review[i]);
        ss.clear();
        ss << review[i];
        k = 0;
        while (ss >> word) {
 
            // If this word is present in the trie
            // then increment its count
            if (search(word, trie))
                k++;
        }
 
        // Store the number of good words in the
        // current string paired with its
        // index in the original array
        rating[i].F = k;
        rating[i].S = i;
    }
 
    // Using comparator function to
    // sort the array as required
    sort(rating.begin(), rating.end(), cmp);
 
    // Print the sorted array
    for (int i = 0; i < n; i++)
        cout << review[rating[i].S] << "\n";
}
 
// Driver code
int main()
{
 
    // String containing good words
    string S = "geeks_for_geeks_is_great";
 
    // Vector of strings to be sorted
    vector<string> R = { "geeks_are_geeks", "geeks_dont_lose",
                        "geeks_for_geeks_is_love" };
 
    // Sort the array based on the given conditions
    sortArr(S, R);
}


Java




import java.util.*;
 
class Program
{
 
  // Comparator function for sorting
  static class PairComparer implements Comparator<Map.Entry<Integer, Integer>> {
    public int compare(Map.Entry<Integer, Integer> a, Map.Entry<Integer, Integer> b) {
 
      // Compare the number of good words
      if (a.getKey().equals(b.getKey())) {
        return a.getValue() - b.getValue();
      }
      return b.getKey() - a.getKey();
    }
  }
 
  // Structure of s Trie node
  static class TrieNode {
    public boolean exist;
    public TrieNode[] arr;
 
    public TrieNode() {
      exist = false;
      arr = new TrieNode[26];
    }
 
    public TrieNode(boolean bul) {
      exist = bul;
      arr = new TrieNode[26];
    }
  }
 
 
  // Function to add a string to the trie
  static void add(String s, TrieNode trie) {
 
    // Add a node to the trie
    int n = s.length();
    for (int i = 0; i < n; i++) {
      int index = s.charAt(i) - 'a';
 
      // If trie doesn't already contain
      // the current node then create one
      if (trie.arr[index] == null) {
        trie.arr[index] = new TrieNode();
      }
      trie = trie.arr[index];
    }
    trie.exist = true;
  }
 
 
  // Function that returns true if
  // the trie contains the string s
  static boolean search(String s, TrieNode trie) {
 
    // Search for a node in the trie
    for (int i = 0; i < s.length(); i++) {
      int index = s.charAt(i) - 'a';
      if (trie.arr[index] == null) {
        return false;
      }
      trie = trie.arr[index];
    }
    return trie.exist;
  }
 
 
  // Function to replace every '_' with a
  // white space in the given string
  static void convert(StringBuilder str) {
 
    // Convert '_' to spaces
    for (int i = 0; i < str.length(); i++) {
      if (str.charAt(i) == '_') {
        str.setCharAt(i, ' ');
      }
    }
  }
 
 
  // Function to sort the array based on good words
  static void sortArr(String good, List<String> review) {
    StringBuilder goodBuilder = new StringBuilder(good);
    convert(goodBuilder);
    TrieNode trie = new TrieNode();
    String[] words = goodBuilder.toString().split(" ");
 
    // Building the entire trie by iterating
    // over the good words string array
    for (String word : words) {
      add(word, trie);
    }
    int n = review.size();
 
    // To store the number of good words
    // and the string index pairs
    List<Map.Entry<Integer, Integer>> rating = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      StringBuilder reviewBuilder = new StringBuilder(review.get(i));
      convert(reviewBuilder);
      words = reviewBuilder.toString().split(" ");
      int k = 0;
      for (String word : words) {
 
        // If this word is present in the trie
        // then increment its count
        if (search(word, trie)) {
          k++;
        }
      }
 
      // Store the number of good words in the
      // current string paired with its
      // index in the original list
      rating.add(Map.entry(k, i));
    }
 
    // Using PairComparer to sort the list as required
    rating.sort(new PairComparer());
 
    // Print the sorted array
    // Print the sorted array
    for (Map.Entry<Integer, Integer> entry : rating) {
      System.out.println(review.get(entry.getValue()));
    }
  }
 
  public static void main(String[] args) {
    String good = "geeks_for_geeks_is_great";
    List<String> review = Arrays.asList("geeks_are_geeks", "geeks_dont_lose", "geeks_for_geeks_is_love");
    sortArr(good, review);
  }
}
 
// This code is contribute by shiv1o43g


Python3




# Python implementation of the approach
MAX = 26
 
# Comparator function for sorting
def cmp(a, b):
    # Compare the number of good words
    if a[0] == b[0]:
        return a[1] < b[1]
    return a[0] > b[0]
 
# Structure of a Trie node
class Node:
    def __init__(self, bul=False):
        self.exist = bul
        self.arr = [None] * MAX
 
# Function to add a string to the trie
def add(s, trie):
    # Add a node to the trie
    n = len(s)
    for i in range(n):
        # If trie doesn't already contain
        # the current node then create one
        if trie.arr[ord(s[i]) - ord('a')] is None:
            trie.arr[ord(s[i]) - ord('a')] = Node()
        trie = trie.arr[ord(s[i]) - ord('a')]
    trie.exist = True
    return
 
# Function that returns true if
# the trie contains the string s
 
 
def search(s, trie):
    # Search for a node in the trie
    for i in range(len(s)):
        if trie.arr[ord(s[i]) - ord('a')] is None:
            return False
        trie = trie.arr[ord(s[i]) - ord('a')]
    return trie.exist
 
# Function to replace every '_' with a
# white space in the given string
 
 
def convert(s):
    # Convert '_' to spaces
    return s.replace('_', ' ')
 
# Function to sort the array based on good words
 
 
def sortArr(good, review):
    # Extract all the good words which
    # are '_' separated
    good = convert(good)
    trie = Node()
    words = good.split()
 
    # Building the entire trie from the good words
    for word in words:
        add(word, trie)
 
    n = len(review)
 
    # To store the number of good words
    # and the string index pairs
    rating = [(0, i) for i in range(n)]
 
    for i in range(n):
        review[i] = convert(review[i])
        words = review[i].split()
        k = 0
 
        for word in words:
            # If this word is present in the trie
            # then increment its count
            if search(word, trie):
                k += 1
 
        # Store the number of good words in the
        # current string paired with its
        # index in the original array
        rating[i] = (k, i)
 
    # Using comparator function to
    # sort the array as required
    rating.sort(key=lambda x: (-x[0], x[1]))
 
    # Print the sorted array
    for r in rating:
        print(review[r[1]])
 
 
# Driver code
if __name__ == '__main__':
    # String containing good words
    S = 'geeks_for_geeks_is_great'
 
    # List of strings to be sorted
    R = ['geeks_are_geeks', 'geeks_dont_lose', 'geeks_for_geeks_is_love']
 
    # Sort the array based on the given conditions
    sortArr(S, R)


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
// Comparator function for sorting
class PairComparer : IComparer<KeyValuePair<int, int>>
{
public int Compare(KeyValuePair<int, int> a, KeyValuePair<int, int> b)
{
// Compare the number of good words
if (a.Key == b.Key)
return a.Value - b.Value;
return b.Key - a.Key;
}
}
 
 
// Structure of s Trie node
class TrieNode
{
    public bool Exist;
    public TrieNode[] Arr;
 
    public TrieNode(bool bul = false)
    {
        Exist = bul;
        Arr = new TrieNode[26];
    }
}
 
// Function to add a string to the trie
static void Add(string s, TrieNode trie)
{
    // Add a node to the trie
    int n = s.Length;
    for (int i = 0; i < n; i++)
    {
        // If trie doesn't already contain
        // the current node then create one
        if (trie.Arr[s[i] - 'a'] == null)
            trie.Arr[s[i] - 'a'] = new TrieNode();
 
        trie = trie.Arr[s[i] - 'a'];
    }
    trie.Exist = true;
    return;
}
 
// Function that returns true if
// the trie contains the string s
static bool Search(string s, TrieNode trie)
{
    // Search for a node in the trie
    for (int i = 0; i < s.Length; i++)
    {
        if (trie.Arr[s[i] - 'a'] == null)
            return false;
 
        trie = trie.Arr[s[i] - 'a'];
    }
    return trie.Exist;
}
 
// Function to replace every '_' with a
// white space in the given string
static void Convert(ref string str)
{
    // Convert '_' to spaces
    for (int i = 0; i < str.Length; i++)
        if (str[i] == '_')
            str = str.Remove(i, 1).Insert(i, " ");
}
 
// Function to sort the array based on good words
static void SortArr(string good, List<string> review)
{
    // Extract all the good words which
    // are '_' separated
    Convert(ref good);
    TrieNode trie = new TrieNode();
    string[] words = good.Split(' ');
 
    // Building the entire trie by iterating
    // over the good words string array
    foreach (string word in words)
        Add(word, trie);
    int k, n = review.Count;
 
    // To store the number of good words
    // and the string index pairs
    List<KeyValuePair<int, int>> rating = new List<KeyValuePair<int, int>>();
    for (int i = 0; i < n; i++)
    {
        string reviewStr = review[i];
        Convert(ref reviewStr);
        words = reviewStr.Split(' ');
        k = 0;
 
        foreach (string word in words)
        {
            // If this word is present in the trie
            // then increment its count
            if (Search(word, trie))
                k++;
        }
 
        // Store the number of good words in the
        // current string paired with its
        // index in the original list
        rating.Add(new KeyValuePair<int, int>(k, i));
    }
 
    // Using PairComparer to sort the list as required
    rating.Sort(new PairComparer());
 
    // Print the sorted array
                   // Print the sorted array
        for (int i = 0; i < n; i++)
        {
            Console.WriteLine(review[rating[i].Value]);
        }
    }
 
    static void Main(string[] args)
    {
        string good = "geeks_for_geeks_is_great";
        List<string> review = new List<string>() {
            "geeks_are_geeks", "geeks_dont_lose",
                        "geeks_for_geeks_is_love"
        };
        SortArr(good, review);
    }
}


Javascript




// JavaScript code for the approach
 
const MAX = 26;
 
// Comparator function for sorting
function cmp(a, b) {
  // Compare the number of good words
  if (a[0] == b[0]) {
    return a[1] - b[1];
  }
  return b[0] - a[0];
}
 
// Structure of a Trie node
class Node {
  constructor(bul) {
    this.exist = bul;
    this.arr = new Array(MAX).fill(null);
  }
}
 
// Function to add a string to the trie
function add(s, trie) {
  // Add a node to the trie
  const n = s.length;
  for (let i = 0; i < n; i++) {
    // If trie doesn't already contain
    // the current node then create one
    if (trie.arr[s.charCodeAt(i) - 'a'.charCodeAt()] === null) {
      trie.arr[s.charCodeAt(i) - 'a'.charCodeAt()] = new Node();
    }
    trie = trie.arr[s.charCodeAt(i) - 'a'.charCodeAt()];
  }
  trie.exist = true;
  return;
}
 
// Function that returns true if
// the trie contains the string s
function search(s, trie) {
  // Search for a node in the trie
  for (let i = 0; i < s.length; i++) {
    if (trie.arr[s.charCodeAt(i) - 'a'.charCodeAt()] === null) {
      return false;
    }
    trie = trie.arr[s.charCodeAt(i) - 'a'.charCodeAt()];
  }
  return trie.exist;
}
 
// Function to replace every '_' with a
// white space in the given string
function convert(s) {
  // Convert '_' to spaces
  return s.replace(/_/g, ' ');
}
 
// Function to sort the array based on good words
function sortArr(good, review) {
  // Extract all the good words which
  // are '_' separated
  good = convert(good);
  const trie = new Node();
  const words = good.split(' ');
 
  // Building the entire trie from the good words
  for (let i = 0; i < words.length; i++) {
    add(words[i], trie);
  }
 
  const n = review.length;
 
  // To store the number of good words
  // and the string index pairs
  const rating = new Array(n).fill(null).map((_, i) => [0, i]);
 
  for (let i = 0; i < n; i++) {
    review[i] = convert(review[i]);
    const words = review[i].split(' ');
    let k = 0;
 
    for (let j = 0; j < words.length; j++) {
      // If this word is present in the trie
      // then increment its count
      if (search(words[j], trie)) {
        k += 1;
      }
    }
 
    // Store the number of good words in the
    // current string paired with its
    // index in the original array
    rating[i] = [k, i];
  }
 
  // Using comparator function to
  // sort the array as required
  rating.sort((a, b) => cmp(a, b));
 
  // Print the sorted array
  for (let i = 0; i < rating.length; i++) {
    console.log(review[rating[i][1]]);
  }
}
 
// Driver code
// Input
let S = 'geeks_for_geeks_is_great';
 
let R = ['geeks_are_geeks', 'geeks_dont_lose', 'geeks_for_geeks_is_love'];
 
// Function Call
sortArr(S, R);


Output

geeks for geeks is love
geeks are geeks
geeks dont lose






Time Complexity: O(N * M * K) where N is the number of reviews, M is the longest length of any review and K is the number of good words.
Auxiliary Space: O(K * 26^L) where K is the number of good words and L is the maximum length of any good word.

Approach (Using Hash Table): The hash table can be used to store the count of each good word in the input string and then sort the vector of strings based on the count of good words for each string.

Algorithm Steps:

  • Define a function cmp as the comparator function for sorting based on the number of good words in a string and its index in the original array.
  • Define a struct node for the Trie data structure and its functions.
  • Define the add and search functions to add and search for a string in the Trie data structure.
  • Define the convert function to replace every ‘_’ with a space in a given string.
  • Define the sortArr function to sort the array based on the given conditions.
  • In sortArr, convert the given good string to a Trie data structure and build it.
  • Loop through the given review vector and count the number of good words present in each string using the search function and store the number of good words in the current string paired with its index in the original array.
  • Sort the array using the cmp comparator function.
  • Print the sorted array.
  • In the main function, define a string containing good words S and a vector of strings to be sorted R.
  • Call the sortArr function passing the S and R as arguments.

Below is he implementation of the above approach:

C++




//C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define MAX 26
 
// Comparator function for sorting
bool cmp(const pair<int, int>& a, const pair<int, int>& b)
{
 
    // Compare the number of good words
    if (a.F == b.F)
        return a.S < b.S;
    return a.F > b.F;
}
 
// Structure of s Trie node
struct node {
    bool exist;
    node* arr[MAX];
    node(bool bul = false)
    {
        exist = bul;
        for (int i = 0; i < MAX; i++)
            arr[i] = NULL;
    }
};
 
// Function to add a string to the trie
void add(string s, node* trie)
{
    // Add a node to the trie
    int n = s.size();
    for (int i = 0; i < n; i++) {
 
        // If trie doesn't already contain
        // the current node then create one
        if (trie->arr[s[i] - 'a'] == NULL)
            trie->arr[s[i] - 'a'] = new node();
 
        trie = trie->arr[s[i] - 'a'];
    }
    trie->exist = true;
    return;
}
 
// Function that returns true if
// the trie contains the string s
bool search(string s, node* trie)
{
    // Search for a node in the trie
    for (int i = 0; i < s.size(); i++) {
        if (trie->arr[s[i] - 'a'] == NULL)
            return false;
 
        trie = trie->arr[s[i] - 'a'];
    }
    return trie->exist;
}
 
// Function to replace every '_' with a
// white space in the given string
void convert(string& str)
{
    // Convert '_' to spaces
    for (int i = 0; i < str.size(); i++)
        if (str[i] == '_')
            str[i] = ' ';
    return;
}
 
// Function to sort the array based on good words
void sortArr(string good, vector<string>& review)
{
 
    // Extract all the good words which
    // are '_' separated
    convert(good);
    node* trie = new node();
    string word;
    stringstream ss;
    ss << good;
 
    // Building the entire trie by stringstreaming
    // the 'good words' string
    while (ss >> word)
        add(word, trie);
    int k, n = review.size();
 
    // To store the number of good words
    // and the string index pairs
    vector<pair<int, int> > rating(n);
    for (int i = 0; i < n; i++) {
        convert(review[i]);
        ss.clear();
        ss << review[i];
        k = 0;
        while (ss >> word) {
 
            // If this word is present in the trie
            // then increment its count
            if (search(word, trie))
                k++;
        }
 
        // Store the number of good words in the
        // current string paired with its
        // index in the original array
        rating[i].F = k;
        rating[i].S = i;
    }
 
    // Using comparator function to
    // sort the array as required
    sort(rating.begin(), rating.end(), cmp);
 
    // Print the sorted array
    for (int i = 0; i < n; i++)
        cout << review[rating[i].S] << "\n";
}
 
// Driver code
int main()
{
 
    // String containing good words
    string S = "geeks_for_geeks_is_great";
 
    // Vector of strings to be sorted
    vector<string> R = { "geeks_are_geeks", "geeks_dont_lose",
                        "geeks_for_geeks_is_love" };
 
    // Sort the array based on the given conditions
    sortArr(S, R);
}


Java




import java.util.*;
 
public class Main {
 
    // Class to store the number of good words
    // and the string index pairs
    static class Rating implements Comparable<Rating> {
        int count;
        int index;
 
        Rating(int count, int index) {
            this.count = count;
            this.index = index;
        }
 
        @Override
        public int compareTo(Rating other) {
            // Custom comparator to sort based on the count in descending order
            if (this.count == other.count) {
                // If counts are the same, sort based on the original index in ascending order
                return Integer.compare(this.index, other.index);
            }
            // Sort based on the count in descending order
            return Integer.compare(other.count, this.count);
        }
    }
 
    // Function to check if a word is present in the trie
    static boolean search(String word, TrieNode trie) {
        TrieNode current = trie;
        for (char ch : word.toCharArray()) {
            if (current.children[ch - 'a'] == null) {
                return false;
            }
            current = current.children[ch - 'a'];
        }
        return current.isEndOfWord;
    }
 
    // Trie data structure
    static class TrieNode {
        TrieNode[] children;
        boolean isEndOfWord;
 
        TrieNode() {
            children = new TrieNode[26];
        }
    }
 
    // Function to build a trie from a list of good words
    static TrieNode buildTrie(List<String> goodWords) {
        TrieNode root = new TrieNode();
        for (String word : goodWords) {
            TrieNode current = root;
            for (char ch : word.toCharArray()) {
                if (current.children[ch - 'a'] == null) {
                    current.children[ch - 'a'] = new TrieNode();
                }
                current = current.children[ch - 'a'];
            }
            current.isEndOfWord = true;
        }
        return root;
    }
 
    // Function to sort the array of strings based on the number of good words
    static void sortArr(String S, List<String> R) {
        int n = R.size();
        List<Rating> rating = new ArrayList<>();
 
        TrieNode trie = buildTrie(Arrays.asList(S.split("_")));
 
        for (int i = 0; i < n; i++) {
            String[] words = R.get(i).split("_");
            int k = 0;
            for (String word : words) {
                if (search(word, trie)) {
                    k++;
                }
            }
            rating.add(new Rating(k, i));
        }
 
        Collections.sort(rating);
 
        for (Rating r : rating) {
            System.out.println(R.get(r.index));
        }
    }
 
    // Driver code
    public static void main(String[] args) {
 
        // String containing good words
        String S = "geeks_for_geeks_is_great";
 
        // List of strings to be sorted
        List<String> R = Arrays.asList("geeks_are_geeks", "geeks_dont_lose", "geeks_for_geeks_is_love");
 
        // Sort the list based on the given conditions
        sortArr(S, R);
    }
}


Python3




from collections import defaultdict
 
# Structure of a Trie node
class TrieNode:
    def __init__(self):
        self.exist = False
        self.children = defaultdict(TrieNode)
 
# Function to add a string to the trie
def add(s, trie):
    for char in s:
        if char not in trie.children:
            trie.children[char] = TrieNode()
        trie = trie.children[char]
    trie.exist = True
 
# Function that returns true if the trie contains the string s
def search(s, trie):
    for char in s:
        if char not in trie.children:
            return False
        trie = trie.children[char]
    return trie.exist
 
# Function to sort the array based on good words
def sortArr(good, review):
    def cmp(a, b):
        if a[0] == b[0]:
            return a[1] < b[1]
        return a[0] > b[0]
 
    # Convert '_' to spaces
    good = good.replace('_', ' ')
 
    trie = TrieNode()
    good_words = good.split()
 
    for word in good_words:
        add(word, trie)
 
    n = len(review)
    rating = []
 
    for i in range(n):
        review[i] = review[i].replace('_', ' ')
        words = review[i].split()
        k = sum(1 for word in words if search(word, trie))
        rating.append((k, i))
 
    rating.sort(key=lambda x: (-x[0], x[1]))
 
    for i in range(n):
        print(review[rating[i][1]])
 
# Driver code
if __name__ == "__main__":
    good = "geeks_for_geeks_is_great"
    reviews = [
        "geeks_are_geeks",
        "geeks_dont_lose",
        "geeks_for_geeks_is_love"
    ]
 
    sortArr(good, reviews)


C#




using System;
using System.Collections.Generic;
 
public class TrieNode
{
    public bool Exist { get; set; }
    public TrieNode[] Arr { get; set; }
 
    public TrieNode()
    {
        Exist = false;
        Arr = new TrieNode[26]; // Initialize an array to hold 26 possible characters ('a' to 'z')
    }
}
 
public class Program
{
    // Function to add a string to the Trie
    public static void Add(string s, TrieNode trie)
    {
        int n = s.Length;
        for (int i = 0; i < n; i++)
        {
            if (trie.Arr[s[i] - 'a'] == null)
            {
                trie.Arr[s[i] - 'a'] = new TrieNode(); // Create a new TrieNode if it doesn't exist
            }
            trie = trie.Arr[s[i] - 'a']; // Move to the next TrieNode
        }
        trie.Exist = true; // Mark the last TrieNode as existing, indicating the end of a word
    }
 
    // Function that returns true if the Trie contains the string s
    public static bool Search(string s, TrieNode trie)
    {
        for (int i = 0; i < s.Length; i++)
        {
            if (trie.Arr[s[i] - 'a'] == null)
            {
                return false; // Return false if a character in the string is not found in the Trie
            }
            trie = trie.Arr[s[i] - 'a']; // Move to the next TrieNode
        }
        return trie.Exist; // Return true if the Trie contains the entire word
    }
 
    // Function to replace every '_' with a whitespace in the given string
    public static string Convert(string str)
    {
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == '_')
            {
                str = str.Substring(0, i) + ' ' + str.Substring(i + 1); // Replace underscores with spaces
            }
        }
        return str;
    }
 
    // Comparator function for sorting
    public static int CompareTuples(Tuple<int, int> a, Tuple<int, int> b)
    {
        if (a.Item1 == b.Item1)
        {
            return a.Item2 - b.Item2;
        }
        return b.Item1 - a.Item1;
    }
 
    // Function to sort the array based on good words
    public static void SortArr(string good, string[] review)
    {
        good = Convert(good); // Replace underscores with spaces in the 'good' string
        TrieNode trie = new TrieNode();
        string[] words = good.Split(' '); // Split the 'good' string into individual words
 
        foreach (string word in words)
        {
            Add(word, trie); // Add each word to the Trie
        }
 
        int n = review.Length;
        List<Tuple<int, int>> rating = new List<Tuple<int, int>>();
 
        for (int i = 0; i < n; i++)
        {
            int k = 0;
            string currentReview = Convert(review[i]); // Replace underscores with spaces in the current review
            string[] reviewWords = currentReview.Split(' '); // Split the review into words
 
            foreach (string word in reviewWords)
            {
                if (Search(word, trie))
                {
                    k++; // Count the number of words in the review that exist in the Trie
                }
            }
 
            rating.Add(new Tuple<int, int>(k, i)); // Add the count and the index to the rating list
        }
 
        rating.Sort(CompareTuples); // Sort the reviews based on the count of good words
 
        foreach (Tuple<int, int> tuple in rating)
        {
            Console.WriteLine(Convert(review[tuple.Item2])); // Output the reviews with spaces instead of underscores
        }
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        string S = "geeks_for_geeks_is_great"; // String containing good words
        string[] R = {
            "geeks_are_geeks",
            "geeks_dont_lose",
            "geeks_for_geeks_is_love"
        }; // Array of reviews
 
        SortArr(S, R); // Call the sorting function
    }
}


Javascript




class TrieNode {
    constructor() {
        this.exist = false;
        this.arr = new Array(26).fill(null);
    }
}
 
// Function to add a string to the Trie
function add(s, trie) {
    let n = s.length;
    for (let i = 0; i < n; i++) {
        if (!trie.arr[s.charCodeAt(i) - 'a'.charCodeAt(0)]) {
            trie.arr[s.charCodeAt(i) - 'a'.charCodeAt(0)] = new TrieNode();
        }
        trie = trie.arr[s.charCodeAt(i) - 'a'.charCodeAt(0)];
    }
    trie.exist = true;
}
 
// Function that returns true if the Trie contains the string s
function search(s, trie) {
    for (let i = 0; i < s.length; i++) {
        if (!trie.arr[s.charCodeAt(i) - 'a'.charCodeAt(0)]) {
            return false;
        }
        trie = trie.arr[s.charCodeAt(i) - 'a'.charCodeAt(0)];
    }
    return trie.exist;
}
 
// Function to replace every '_' with a whitespace in the given string
function convert(str) {
    for (let i = 0; i < str.length; i++) {
        if (str[i] === '_') {
            str = str.substring(0, i) + ' ' + str.substring(i + 1);
        }
    }
    return str;
}
 
// Comparator function for sorting
function compareTuples(a, b) {
    if (a[0] === b[0]) {
        return a[1] - b[1];
    }
    return b[0] - a[0];
}
 
// Function to sort the array based on good words
function sortArr(good, review) {
    good = convert(good);
    const trie = new TrieNode();
    const words = good.split(' ');
 
    for (const word of words) {
        add(word, trie);
    }
 
    const n = review.length;
    const rating = [];
 
    for (let i = 0; i < n; i++) {
        let k = 0;
        let currentReview = convert(review[i]);
        const reviewWords = currentReview.split(' ');
 
        for (const word of reviewWords) {
            if (search(word, trie)) {
                k++;
            }
        }
 
        rating.push([k, i]);
    }
 
    rating.sort(compareTuples);
 
    for (const tuple of rating) {
        console.log(review[tuple[1]]);
    }
}
 
// Driver code
const S = "geeks_for_geeks_is_great";
const R = [
    "geeks_are_geeks",
    "geeks_dont_lose",
    "geeks_for_geeks_is_love"
];
 
sortArr(S, R);


Output

geeks for geeks is love
geeks are geeks
geeks dont lose







Time Complexity: O(NMlogM), where N is the number of strings in the vector and M is the maximum length of a string in the vector.

Auxiliary Space: O(M^2 + NM), where M^2 is the space required for the trie and NM is the space required for the vector and other variables.



Last Updated : 12 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads