我正在C ++中使用STL映射来计算文本文件中单词的出现频率,并且单词必须按字典顺序排序。输入数据以文本文件形式给出。香港专业教育学院已经阅读并将其添加到地图中,但我在排序时遇到问题。
例如,我有{“ Abc”,“ abc”,“ bag”,“ Boom”,“ great”}。当我将它们添加到地图中时,我得到了
Abc 1臂杆1 abc 1袋1大1
但预期结果是
Abc 1 abc 1吊杆1袋1很棒1
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
using namespace std;
typedef map<string, int> word_count;
int main(){
word_count wc;
fstream f_in;
f_in.open("test.in");
string x;
while( !f_in.eof()){
f_in >> x;
wc[x]++;
}
f_in.close();
return 0;
}
这是我读取输入的代码。对我的问题有帮助吗?谢谢
答案 0 :(得分:2)
OP希望使用一个自定义排序顺序,该顺序与标准词典顺序略有不同。可以通过传递自定义map
(Compare
是Compare
的第三个模板参数)来实现具有自定义排序顺序的map
:
#include <algorithm>
#include <cctype>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using std::string;
using std::transform;
using std::map;
using std::cout;
struct Compare {
bool operator() (const string& s0, const string& s1) const {
// construct all lowercase versions of s0 and s1
string str0(s0.length(),' ');
string str1(s1.length(),' ');
transform(s0.begin(), s0.end(), str0.begin(), tolower);
transform(s1.begin(), s1.end(), str1.begin(), tolower);
if (!str0.empty() and !str1.empty() and str0.front()==str1.front()) {
// do a standard lexicographic sort if the first character is the same
return s0 < s1;
}
else {
// otherwise, do a case-insensitive lexicographic sort using the lowercased strings
return str0 < str1;
}
}
};
typedef map<string, int, Compare> word_count;
int main(){
word_count wc;
auto words = { "Abc", "abc", "bag", "Boom", "great"};
for (auto word : words)
wc[word]++;
for(auto elem : wc)
cout << elem.first << " " << elem.second << '\n';
return 0;
}
这确实会产生所需的输出:
Abc 1
abc 1
Boom 1
bag 1
great 1
Try out a live version of the code online
默认情况下,地图的第三个模板参数为less<key>
(在这种情况下为less<string>
),它将按标准的字典顺序A-z
排序字符串。
答案 1 :(得分:1)
这是一个完整的示例,其中包含文件读取功能,并使用了std::map
的基本排序功能。
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
typedef std::map<std::string, int> word_count;
int main(int argc, char** argv){
if(argc < 2){
std::cout << "Please provide a file name." << std::endl;
return 1;
}
word_count wc;
std::ifstream inputfile(argv[1]);
if (inputfile.is_open()){
std::string x;
while(inputfile >> x){
wc[x]++;
}
inputfile.close();
}else {std::cout << "Program aborted: unable to open input file" << std::endl; return 1;}
for(auto word: wc){
std::cout << word.first << "\t" << word.second << std::endl;
}
return 0;
}