在C ++中创建自定义比较器

背景

我今天在一次在线实践面试中被问到了这个问题,我很难找出一个自定义的比较器进行排序。这是问题

问题:

  

实现一个文档扫描功能wordCountEngine,该功能接收一个字符串文档,并返回其中包含的所有唯一单词及其出现次数的列表,并按出现次数从高到低排序。如果两个或多个单词具有相同的计数,则应根据它们在原始句子中的顺序进行排序。假设所有字母都是英文字母。您的函数应不区分大小写,例如,“ Perfect”和“ perfect”一词应视为同一词。

     

引擎应去除标点符号(即使在单词中间),并使用空格分隔单词。

     

分析解决方案的时间和空间复杂性。尝试优化时间,同时保持多项式空间的复杂性。

     

示例:

     

输入:document =“实践完美。您只会                       通过实践获得完美。练习吧!”

     

输出:[[“练习”,“ 3”],[“完美”,“ 2”],             [“ makes”,“ 1”],[“ youll”,“ 1”],[“ only”,“ 1”],             [“ get”,“ 1”],[“ by”,“ 1”],[“ just”,“ 1”]]

我的想法:

我想做的第一件事是首先获取不带标点的字符串,并将所有字母都小写成字符串向量。然后,我使用了unordered_map容器来存储字符串和它的出现次数。卡住的地方是创建一个自定义比较器,以确保如果我有一个具有相同计数的字符串,那么我将根据它在实际给定字符串中的优先级对其进行排序。

代码:

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <sstream>
#include <iterator>
#include <numeric>
#include <algorithm>
using namespace std;


struct cmp
{
  bool operator()(std::string& word1,std::string& word2)
  {

  }
};

vector<vector<string>> wordCountEngine( const string& document ) 
{
  // your code goes here
  // Step 1
  auto doc = document;
  std::string str;
  remove_copy_if(doc.begin(),doc.end(),std::back_inserter(str),std::ptr_fun<int,int>(&std::ispunct));
  for(int i = 0; i < str.size(); ++i)
    str[i] = tolower(str[i]);
  std::stringstream ss(str);
  istream_iterator<std::string> begin(ss);
  istream_iterator<std::string> end;
  std::vector<std::string> vec(begin,end);

  // Step 2
  std::unordered_map<std::string,int> m;
  for(auto word : vec)
    m[word]++;

  // Step 3
  std::vector<std::vector<std::string>> result;
  for(auto it : m)
  {
    result.push_back({it.first,std::to_string(it.second)});
  }


  return result;

}

int main() {

  std::string document = "Practice makes perfect. you'll only get Perfect by practice. just practice!";
  auto result = wordCountEngine(document);
  for(int i = 0; i < result.size(); ++i)
  {
    for(int j = 0; j < result[0].size(); ++j)
    {
      std::cout << result[i][j] << " ";
    }
    std::cout << "\n";
  }

  return 0;
}

如果有人可以帮助我学习如何为此代码构建自定义比较器,我将不胜感激。

q4023586 回答:在C ++中创建自定义比较器

您可以使用std::vector<std::pair<std::string,int>>,每对代表一个单词以及该单词在序列中出现的次数。当两个或多个单词具有相同的计数时,使用向量将有助于保持原始序列的顺序。最后按出现次数排序。

#include <vector>
#include <algorithm>
#include <string>
#include <sstream>

std::vector<std::vector<std::string>> wordCountEngine(const std::string& document)
{
    std::vector<std::pair<std::string,int>> words;
    std::istringstream ss(document);
    std::string word;

    //Loop through words in sequence
    while (getline(ss,word,' '))
    {
        //Convert to lowercase
        std::transform(word.begin(),word.end(),word.begin(),tolower);

        //Remove punctuation characters
        auto it = std::remove_if(word.begin(),[](char c) { return !isalpha(c); });
        word.erase(it,word.end());

        //Find this word in the result vector
        auto pos = std::find_if(words.begin(),words.end(),[&word](const std::pair<std::string,int>& p) { return p.first == word; });
        if (pos == words.end()) {
            words.push_back({ word,1 });  //Doesn't occur -> add it
        }
        else {
            pos->second++;                 //Increment count
        }
    }

    //Sort vector by word occurrences
    std::sort(words.begin(),[](const std::pair<std::string,int>& p1,const std::pair<std::string,int>& p2) { return p1.second > p2.second; });

    //Convert to vector<vector<string>>
    std::vector<std::vector<std::string>> result;
    result.reserve(words.size());

    for (auto& p : words)
    {
        std::vector<std::string> v = { p.first,std::to_string(p.second) };
        result.push_back(v);
    }
    return result;
}

int main()
{
    std::string document = "Practice makes perfect. you'll only get Perfect by practice. just practice!";
    auto result = wordCountEngine(document);
    for (auto& word : result)
    {
        std::cout << word[0] << "," << word[1] << std::endl;
    }
    return 0;
}

输出:
练习3
完美2
制作1
你1岁
只有1
得到1
通过,1
只是1

,

在步骤2中,尝试以下操作:

std::vector<std::pair<std::pair<std::string,int>,int>> m;

在这里,该对存储字符串和它的出现索引,向量存储该对和它的出现计数。编写一个逻辑,首先根据计数排序,然后如果计数相同,则根据发生的位置对其进行排序。

bool sort_vector(const std::pair<const std::pair<std::string,int> &a,const std::pair<const std::pair<std::string,int> &b)
{
    if(a.second==b.second)
    {
        return a.first.second<b.first.second
        // This will make sure that if the no of occurances of each string is same,then it will be sorted according to the position of the string
    }
    return a.second>b.second
    //This will make sure that the strings are sorted in the order to return the string having higher no of occurances first.
}

您必须编写逻辑以计算字符串中每个单词的出现次数和出现索引。

本文链接:https://www.f2er.com/3112627.html

大家都在问