我有一个WordEntry类,它有一个unordered_map<string, int>,我想存储每个单词的频率。我可以这样做,但我也想向用户显示前5个单词和底部5个单词。要做到这一点,我必须整理一下。但是,我得到了一个非常可怕的、令人讨厌的错误,这个错误与您通常的c++异常不一样。我不知道是否包括在内会有很大帮助,因为它是相当长的。这是我的wordentry.h
#ifndef WORDENTRY_H
#define WORDENTRY_H
#include "node.h"
#include "bst.h"
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;
template <class T>
class WordEntry
{
public:
int retrieveWordFreq(Node<T> *);
void collectWords(T data);
void getTop5();
void getBot5();
unordered_map<T, int> freqs;
private:
int freq = 0;
bool sortByVal( pair<string, int> &a, pair<string, int> &b);
};
template <class T>
int WordEntry<T>::retrieveWordFreq(Node<T> *word)
{
}
template <class T>
void WordEntry<T>::getTop5()
{
vector<pair<string, int>> vec;
// copy key-value pairs from the map to the vector
unordered_map<string, int>::iterator it2;
for (it2 = freqs.begin(); it2 != freqs.end(); it2++)
{
vec.push_back(make_pair(it2->first, it2->second));
}
// // sort the vector by increasing order of its pair's second value
sort(vec.begin(), vec.end(), sortByVal);
for (int i = vec.size() - 1; i > vec.size() - 6; i--)
{
cout << vec[i].first << ": " << vec[i].second << endl;
}
}
template <class T>
void WordEntry<T>::getBot5()
{
vector<pair<string, int>> vec;
for (auto& it : freqs) {
vec.push_back(it);
}
sort(vec.begin(), vec.end(), sortByVal);
for (int i = 0; i < 6; i++)
{
cout << vec[i].first << ": " << vec[i].second << endl;
}
}
template <class T>
void WordEntry<T>::collectWords(T val)
{
freqs[val]++;
}
template <class T>
bool WordEntry<T>::sortByVal(pair<string, int> &a, pair<string, int> &b)
{
return (a.second < b.second);
}
#endif还有我的主菜
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_set>
#include "bst.h"
#include "wordentry.h"
using namespace std;
int main()
{
fstream file;
string word, filename;
BST<string> wordTree;
unordered_set<string> set;
WordEntry<string> words;
filename = "file.txt";
file.open(filename.c_str());
while (file >> word)
{
wordTree.insert(word);
words.collectWords(word);
}
cout << "Words amount: " << wordTree.length() << "\n";
cout << "Unique Words amount: " << set.size() << "\n";
words.getBot5();
int choice;
cout << "What do you want to do?\n1. Enter a word and find it's frequency\n2.Output frequency analysis to a file\n";
cin >> choice;
if (choice == 1) {
string word;
cout << "Enter the word you want the frequency of \n";
cin >> word;
for (auto x : words.freqs)
{
if (x.first == word)
{
cout << x.second;
}
}
}
else if (choice == 2)
{
ofstream outfile ("output.txt");
outfile << "Words amount: " << wordTree.length() << "\n";
outfile << "Unique Words amount: " << set.size() << "\n";
}
return 0;
}words.getBot5();是罪魁祸首,这意味着我的实现是错误的,但我不知道为什么。我只是将密钥对复制到向量并进行排序。
编辑:这是错误
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algobase.h:71:0,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\char_traits.h:39,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ios:40,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ostream:38,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\iostream:39,
from driver.cpp:1:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of
'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> >
>; _Iterator2 = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1844:14: required from 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >;
_Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1882:25: required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1968:31: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4739:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]'
wordentry.h:62:9: required from 'void WordEntry<T>::getBot5() [with T = std::__cxx11::basic_string<char>]'
driver.cpp:34:19: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:123:18: error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp) (...)'
{ return bool(_M_comp(*__it1, *__it2)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of
'bool __gnu_cxx::__ops::_Iter_comp_val<_Compare>::operator()(_Iterator, _Value&) [with _Iterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>,
int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Value = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:129:48: required from 'void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with
_RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Distance = int; _Tp = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = __gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:230:23: required from 'void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >;
_Distance = int; _Tp = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:335:22: required from 'void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1669:23: required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1930:25: required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&,
std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1945:27: required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Size = int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1965:25: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4739:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]'
wordentry.h:62:9: required from 'void WordEntry<T>::getBot5() [with T = std::__cxx11::basic_string<char>]'
driver.cpp:34:19: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:144:11: error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp) (...)'
{ return bool(_M_comp(*__it, __val)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~发布于 2021-05-02 01:10:33
你需要做一些不同的事情。
首先,您必须使比较器static如下所示:
template <class T>
class WordEntry
{
public:
// int retrieveWordFreq(Node<T> *);
void collectWords(T data);
void getTop5();
void getBot5();
unordered_map<T, int> freqs;
private:
int freq = 0;
static bool sortByVal( pair<string, int> &a, pair<string, int> &b); // static
};因为普通成员函数指针比静态成员函数更复杂,因为它们需要一个对象来操作。
第二,你必须用它的限定名称来称呼它:
sort(vec.begin(), vec.end(), WordEntry<T>::sortByVal); // qualified name发布于 2021-05-02 03:48:39
可以在不对列表进行排序的情况下完成这一任务,并且运行速度要快得多,特别是对于大型列表。
要获得最大或最小的项,只需扫描一次列表并跟踪一个变量。如果您发现一个比当前最大的条目更大的条目,只需将其复制到最大的条目即可。如果您发现一个比当前最小项更小的条目,只需将其复制到最小项中即可。
给定一个大小为N的数组,下面的伪代码将找到最大或最小的。
Copy = array[0];
foreach Entry in array
if searching for largest and Entry > Copy, set Copy = Entry
if searching for smallest and Entry < Copy, set Copy = Entry当此代码完成时,副本包含最大或最小的副本。此代码的运行时为O(n),而排序第一,取最大或最小的运行时为O(n * lg(n))。
对于任何固定大小的K,只需复制一个大小为K的数组。伪代码的变化很小。
首先,我们假设存在一个函数Find_S_or_L_In_Copy(),该函数返回复制数组中最小或最大项的索引。
其次,我们使用这个函数来帮助跟踪最小或最大的K项。
foreach Slot in Copy
Copy[Slot] = Array[0]
foreach Entry in Array
if searching for largest K
set Item = Find_S_or_L_In_Copy()
if Entry > Copy[Item], set Copy[Item] = Entry
if searching for smallest K
set Item = Find_S_or_L_In_Copy()
if Entry < Copy[Item], set Copy[Item] = Entry当这些新代码退出时,数组Copy将包含来自Array的K最大或最小的条目。此代码的运行时为O(N * K)。
https://stackoverflow.com/questions/67352068
复制相似问题