在地图C ++中按字典顺序排序

时间:2018-11-11 00:04:22

标签: c++

我正在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;
}

这是我读取输入的代码。对我的问题有帮助吗?谢谢

2 个答案:

答案 0 :(得分:2)

OP希望使用一个自定义排序顺序,该顺序与标准词典顺序略有不同。可以通过传递自定义mapCompareCompare的第三个模板参数)来实现具有自定义排序顺序的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;
}