📌  相关文章
📜  第一个数组中的字符串计数小于第二个数组中的每个字符串

📅  最后修改于: 2021-04-28 18:18:57             🧑  作者: Mango

给定两个数组A []B [] ,它们分别由NM个字符串组成。字符串S1被说成是比字符串S2小,如果在S1中的最小字符的频率比S2中的最小字符的频率小。任务是为每个i计算A []中小于B [i]的字符串数。

例子:

一个幼稚的方法是获取B []中的每个字符串,然后计算A []中满足条件的字符串数。

一种有效的方法是使用二进制搜索和如下所述的一些预先计算来解决该问题:

  • 最初计算每个字符串的最小字符的频率,并将其存储在向量/数组中。
  • 按升序对向量/数组进行排序。
  • 现在,对于B [i]中的每个字符串,找到最小字符的频率。
  • 使用C++中的lower_bound函数,或通过在向量/数组中进行二进制搜索,找到频率小于每个B [i]最小字符频率的数字计数。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define MAX 26
// Function to count the number of smaller
// strings in A[] for every string in B[]
vector findCount(string a[], string b[], int n, int m)
{
  
    // Count the frequency of all characters
    int freq[MAX] = { 0 };
  
    vector smallestFreq;
  
    // Iterate for all possible strings in A[]
    for (int i = 0; i < n; i++) {
        string s = a[i];
        memset(freq, 0, sizeof freq);
  
        // Increase the frequency of every character
        for (int j = 0; j < s.size(); j++) {
            freq[s[j] - 'a']++;
        }
  
        // Check for the smallest character's frequency
        for (int j = 0; j < MAX; j++) {
  
            // Get the smallest character frequency
            if (freq[j]) {
  
                // Insert it in the vector
                smallestFreq.push_back(freq[j]);
                break;
            }
        }
    }
  
    // Sort the count of all the frequency of the smallest
    // character in every string
    sort(smallestFreq.begin(), smallestFreq.end());
  
    vector ans;
  
    // Iterate for every string in B[]
    for (int i = 0; i < m; i++) {
        string s = b[i];
  
        // Hash set every frequency 0
        memset(freq, 0, sizeof freq);
  
        // Count the frequency of every character
        for (int j = 0; j < s.size(); j++) {
            freq[s[j] - 'a']++;
        }
  
        int frequency = 0;
  
        // Find the frequency of the smallest character
        for (int j = 0; j < MAX; j++) {
            if (freq[j]) {
                frequency = freq[j];
                break;
            }
        }
  
        // Count the number of strings in A[]
        // which has the frequency of the smaller
        // character less than the frequency of the
        // smaller character of the string in B[]
        int ind = lower_bound(smallestFreq.begin(),
                              smallestFreq.end(), frequency)
                  - smallestFreq.begin();
  
        // Store the answer
        ans.push_back(ind);
    }
  
    return ans;
}
  
// Function to print the answer
void printAnswer(string a[], string b[], int n, int m)
{
  
    // Get the answer
    vector ans = findCount(a, b, n, m);
  
    // Print the number of strings
    // for every answer
    for (auto it : ans) {
        cout << it << " ";
    }
}
  
// Driver code
int main()
{
    string A[] = { "aaa", "aa", "bdc" };
    string B[] = { "cccch", "cccd" };
    int n = sizeof(A) / sizeof(A[0]);
    int m = sizeof(B) / sizeof(B[0]);
  
    printAnswer(A, B, n, m);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
class GFG
{
    static int MAX = 26;
      
    // Function to count the number of smaller
    // strings in A[] for every String in B[]
    static Vector findCount(String a[], 
                                     String b[], 
                                     int n, int m)
    {
      
        // Count the frequency of all characters
        int []freq = new int[MAX];
      
        Vector smallestFreq = new Vector();
      
        // Iterate for all possible strings in A[]
        for (int i = 0; i < n; i++) 
        {
            String s = a[i];
            Arrays.fill(freq, 0);
              
            // Increase the frequency of every character
            for (int j = 0; j < s.length(); j++) 
            {
                freq[s.charAt(j) - 'a']++;
            }
      
            // Check for the smallest character's frequency
            for (int j = 0; j < MAX; j++)
            {
      
                // Get the smallest character frequency
                if (freq[j] > 0) 
                {
      
                    // Insert it in the vector
                    smallestFreq.add(freq[j]);
                    break;
                }
            }
        }
      
        // Sort the count of all the frequency of
        // the smallest character in every string
        Collections.sort(smallestFreq);
      
        Vector ans = new Vector();
      
        // Iterate for every String in B[]
        for (int i = 0; i < m; i++) 
        {
            String s = b[i];
      
            // Hash set every frequency 0
            Arrays.fill(freq, 0);
      
            // Count the frequency of every character
            for (int j = 0; j < s.length(); j++) 
            {
                freq[s.charAt(j) - 'a']++;
            }
      
            int frequency = 0;
      
            // Find the frequency of the smallest character
            for (int j = 0; j < MAX; j++)
            {
                if (freq[j] > 0)
                {
                    frequency = freq[j];
                    break;
                }
            }
      
            // Count the number of strings in A[]
            // which has the frequency of the smaller
            // character less than the frequency of the
            // smaller character of the String in B[]
            int [] array = new int[smallestFreq.size()];
            int k = 0;
            for(Integer val:smallestFreq)
            {
                array[k] = val;
                k++;
            }
                  
            int ind = lower_bound(array, 0, 
                                  smallestFreq.size(), 
                                  frequency);
      
            // Store the answer
            ans.add(ind);
        }
        return ans;
    }
      
    static int lower_bound(int[] a, int low, 
                           int high, int element)
    {
        while(low < high)
        {
            int middle = low + (high - low) / 2;
            if(element > a[middle])
                low = middle + 1;
            else
                high = middle;
        }
        return low;
    } 
      
    // Function to print the answer
    static void printAnswer(String a[], String b[],
                            int n, int m)
    {
      
        // Get the answer
        Vector ans = findCount(a, b, n, m);
      
        // Print the number of strings
        // for every answer
        for (Integer it : ans) 
        {
            System.out.print(it + " ");
        }
    }
      
    // Driver code
    public static void main(String[] args) 
    {
        String A[] = { "aaa", "aa", "bdc" };
        String B[] = { "cccch", "cccd" };
        int n = A.length;
        int m = B.length;
      
        printAnswer(A, B, n, m);
    }
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
from bisect import bisect_left as lower_bound
  
MAX = 26
  
# Function to count the number of smaller
# strings in A for every in B
def findCount(a, b, n, m):
  
    # Count the frequency of all characters
    freq=[0 for i in range(MAX)]
  
    smallestFreq=[]
  
    # Iterate for all possible strings in A
    for i in range(n):
        s = a[i]
  
        for i in range(MAX):
            freq[i]=0
  
        # Increase the frequency of every character
        for j in range(len(s)):
            freq[ord(s[j]) - ord('a')]+= 1
  
        # Check for the smallest character's frequency
        for j in range(MAX):
  
            # Get the smallest character frequency
            if (freq[j]):
  
                # Insert it in the vector
                smallestFreq.append(freq[j])
                break
  
  
    # Sort the count of all the frequency of the smallest
    # character in every string
    smallestFreq=sorted(smallestFreq)
  
    ans=[]
  
    # Iterate for every in B
    for i in range(m):
        s = b[i]
  
        # Hash set every frequency 0
        for i in range(MAX):
            freq[i]=0
  
        # Count the frequency of every character
        for j in range(len(s)):
            freq[ord(s[j]) - ord('a')]+= 1
  
  
        frequency = 0
  
        # Find the frequency of the smallest character
        for j in range(MAX):
            if (freq[j]):
                frequency = freq[j]
                break
  
        # Count the number of strings in A
        # which has the frequency of the smaller
        # character less than the frequency of the
        # smaller character of the in B
        ind = lower_bound(smallestFreq,frequency)
  
        # Store the answer
        ans.append(ind)
  
    return ans
  
  
# Function to print the answer
def printAnswer(a, b, n, m):
  
    # Get the answer
    ans = findCount(a, b, n, m)
  
    # Print the number of strings
    # for every answer
    for it in ans:
        print(it,end=" ")
  
# Driver code
  
A = ["aaa", "aa", "bdc"]
B = ["cccch", "cccd"]
n = len(A)
m = len(B)
  
printAnswer(A, B, n, m)
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;    
public class GFG
{
    static int MAX = 26;
       
    // Function to count the number of smaller
    // strings in A[] for every String in B[]
    static List findCount(String []a, 
                                     String []b, 
                                     int n, int m)
    {
       
        // Count the frequency of all characters
        int []freq = new int[MAX];
       
        List smallestFreq = new List();
       
        // Iterate for all possible strings in A[]
        for (int i = 0; i < n; i++) 
        {
            String s = a[i];
            for (int l = 0; l < freq.Length; l++)
                freq[l]=0;
               
            // Increase the frequency of every character
            for (int j = 0; j < s.Length; j++) 
            {
                freq[s[j] - 'a']++;
            }
       
            // Check for the smallest character's frequency
            for (int j = 0; j < MAX; j++)
            {
       
                // Get the smallest character frequency
                if (freq[j] > 0) 
                {
       
                    // Insert it in the vector
                    smallestFreq.Add(freq[j]);
                    break;
                }
            }
        }
       
        // Sort the count of all the frequency of
        // the smallest character in every string
        smallestFreq.Sort();
       
        List ans = new List();
       
        // Iterate for every String in B[]
        for (int i = 0; i < m; i++) 
        {
            String s = b[i];
       
            // Hash set every frequency 0
            for (int l = 0; l < freq.Length; l++)
                freq[l]=0;
       
            // Count the frequency of every character
            for (int j = 0; j < s.Length; j++) 
            {
                freq[s[j] - 'a']++;
            }
       
            int frequency = 0;
       
            // Find the frequency of the smallest character
            for (int j = 0; j < MAX; j++)
            {
                if (freq[j] > 0)
                {
                    frequency = freq[j];
                    break;
                }
            }
       
            // Count the number of strings in A[]
            // which has the frequency of the smaller
            // character less than the frequency of the
            // smaller character of the String in B[]
            int [] array = new int[smallestFreq.Count];
            int k = 0;
            foreach (int val in smallestFreq)
            {
                array[k] = val;
                k++;
            }
                   
            int ind = lower_bound(array, 0, 
                                  smallestFreq.Count, 
                                  frequency);
       
            // Store the answer
            ans.Add(ind);
        }
        return ans;
    }
       
    static int lower_bound(int[] a, int low, 
                           int high, int element)
    {
        while(low < high)
        {
            int middle = low + (high - low) / 2;
            if(element > a[middle])
                low = middle + 1;
            else
                high = middle;
        }
        return low;
    } 
       
    // Function to print the answer
    static void printAnswer(String []a, String []b,
                            int n, int m)
    {
       
        // Get the answer
        List ans = findCount(a, b, n, m);
       
        // Print the number of strings
        // for every answer
        foreach (int it in ans) 
        {
            Console.Write(it + " ");
        }
    }
       
    // Driver code
    public static void Main(String[] args) 
    {
        String []A = { "aaa", "aa", "bdc" };
        String []B = { "cccch", "cccd" };
        int n = A.Length;
        int m = B.Length;
       
        printAnswer(A, B, n, m);
    }
}
// This code is contributed by Princi Singh


输出:
3 2