📌  相关文章
📜  第一个字符串中最常见的单词,第二个字符串中不存在

📅  最后修改于: 2021-05-07 08:06:32             🧑  作者: Mango

给定两个字符串“ S1”和“ S2”,任务是从“ S2”中不存在的“ S1”中返回最频繁的单词(使用次数最多)。如果可以使用多个单词,则按字典顺序在其中最小打印。

例子:

方法:思考过程必须从创建映射以存储键值对(字符串,int)开始。随后,在更新映射和计数的同时开始从第一个字符串提取单词。对于第一个数组中存在的第二个数组中的每个单词,重置计数。最后,遍历地图,找到频率最高的单词,然后按字典顺序得到最小的单词。

算法:

  1. 遍历字符串S2并创建一个映射,并将其中的所有单词插入到映射中。
  2. 遍历字符串S1并检查在上一步创建的映射中是否不存在该单词。
  3. 如果单词满足条件,则直到现在为止相同单词的频率最大时,才更新答案。
  4. 如果单词的频率等于先前选择的单词,则根据两个字符串按字典顺序最小的单词来更新答案。

下面是上述方法的实现:

C++
// CPP implementation of above approach
#include 
using namespace std;
  
// Function to return frequent
// word from S1 that isn't
// present in S2
string smallestFreq(string S1, string S2)
{
  
    map banned;
  
    // create map of banned words
    for (int i = 0; i < S2.length(); ++i) {
  
        string s = "";
        while (i < S2.length() && S2[i] != ' ')
            s += S2[i++];
  
        banned[s]++;
    }
  
    map result;
    string ans;
    int freq = 0;
  
    // find smallest and most frequent word
    for (int i = 0; i < S1.length(); ++i) {
  
        string s = "";
        while (i < S1.length() && S1[i] != ' ')
            s += S1[i++];
  
        // check if word is not banned
        if (banned[s] == 0) {
            result[s]++;
            if (result[s] > freq
                || (result[s] == freq && s < ans)) {
                ans = s;
                freq = result[s];
            }
        }
    }
  
    // return answer
    return ans;
}
  
// Driver program
int main()
{
    string S1 = "geeks for geeks is best place to learn";
    string S2 = "bad place";
  
    cout << smallestFreq(S1, S2);
  
    return 0;
}


Java
// Java implementation of above approach 
import java.util.HashMap;
  
class GFG 
{
  
    // Function to return frequent
    // word from S1 that isn't
    // present in S2
    static String smallestFreq(String S1,
                               String S2) 
    {
        HashMap banned = new HashMap<>();
  
        // create map of banned words
        for (int i = 0; i < S2.length(); i++)
        {
            String s = "";
            while (i < S2.length() && 
                       S2.charAt(i) != ' ')
                s += S2.charAt(i++);
  
            banned.put(s, banned.get(s) == null ? 
                      1 : banned.get(s) + 1);
        }
  
        HashMap result = new HashMap<>();
        String ans = "";
        int freq = 0;
  
        // find smallest and most frequent word
        for (int i = 0; i < S1.length(); i++) 
        {
            String s = "";
            while (i < S1.length() && 
                       S1.charAt(i) != ' ')
                s += S1.charAt(i++);
  
            // check if word is not banned
            if (banned.get(s) == null)
            {
                result.put(s, result.get(s) == null ? 1 : 
                              result.get(s) + 1);
                if (result.get(s) > freq || 
                   (result.get(s) == freq && 
                    s.compareTo(ans) < 0))
                {
                    ans = s;
                    freq = result.get(s);
                }
            }
        }
  
        // return answer
        return ans;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String S1 = "geeks for geeks is best place to learn";
        String S2 = "bad place";
        System.out.println(smallestFreq(S1, S2));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of above approach 
from collections import defaultdict
  
# Function to return frequent 
# word from S1 that isn't 
# present in S2 
def smallestFreq(S1, S2): 
  
    banned = defaultdict(lambda:0)
      
    i = 0
      
    # create map of banned words 
    while i < len(S2): 
  
        s = "" 
        while i < len(S2) and S2[i] != ' ': 
            s += S2[i]
            i += 1
              
        i += 1
        banned[s] += 1
  
    result = defaultdict(lambda:0) 
    ans = ""
    freq = 0
    i = 0
      
    # find smallest and most frequent word 
    while i < len(S1): 
  
        s = "" 
        while i < len(S1) and S1[i] != ' ': 
            s += S1[i]
            i += 1
          
        i += 1
          
        # check if word is not banned 
        if banned[s] == 0:
            result[s] += 1
              
            if (result[s] > freq or 
               (result[s] == freq and s < ans)):
                ans = s 
                freq = result[s] 
              
    # return answer 
    return ans 
  
# Driver Code
if __name__ == "__main__": 
  
    S1 = "geeks for geeks is best place to learn"
    S2 = "bad place"
  
    print(smallestFreq(S1, S2)) 
  
# This code is contributed 
# by Rituraj Jain


C#
// C# implementation of above approach
using System;
using System.Collections.Generic; 
      
class GFG 
{
  
    // Function to return frequent
    // word from S1 that isn't
    // present in S2
    static String smallestFreq(String S1,
                               String S2) 
    {
        Dictionary banned = new Dictionary();
  
        // create map of banned words
        for (int i = 0; i < S2.Length; i++)
        {
            String s = "";
            while (i < S2.Length && 
                    S2[i] != ' ')
                s += S2[i++];
  
            if(banned.ContainsKey(s))
            {
                var val = banned[s];
                banned.Remove(s);
                banned.Add(s, val + 1); 
            }
            else
            {
                banned.Add(s, 1);
            }
        }
  
        Dictionary result = new Dictionary();
        String ans = "";
        int freq = 0;
  
        // find smallest and most frequent word
        for (int i = 0; i < S1.Length; i++) 
        {
            String s = "";
            while (i < S1.Length && 
                    S1[i] != ' ')
                s += S1[i++];
  
            // check if word is not banned
            if (!banned.ContainsKey(s))
            {
                if(result.ContainsKey(s))
                {
                    var val = result[s];
                    result.Remove(s);
                    result.Add(s, val + 1); 
                }
                else
                {
                    result.Add(s, 1);
                }
                if (result[s] > freq || 
                   (result[s] == freq && 
                    s.CompareTo(ans) < 0))
                {
                    ans = s;
                    freq = result[s];
                }
            }
        }
  
        // return answer
        return ans;
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        String S1 = "geeks for geeks is best place to learn";
        String S2 = "bad place";
        Console.WriteLine(smallestFreq(S1, S2));
    }
}
  
// This code is contributed by PrinciRaj1992


输出:
geeks

复杂度分析:

  • 时间复杂度: O(n),其中n是字符串的长度。
    需要对字符串一次遍历。
  • 空间复杂度: O(n)。
    一个字符串中最多可以有n个单词。该映射需要O(n)空间来存储字符串。