【问题标题】:sort in lexicographic order in map C++在地图C ++中按字典顺序排序
【发布时间】:2018-11-11 00:04:22
【问题描述】:

我在 C++ 中使用 STL 映射来计算文本文件中单词的频率,并且单词必须按字典顺序排序。输入数据以文本文件的形式给出。我已经阅读并在地图中添加了它们,但我在排序时遇到了问题。

例如,我有 { "Abc", "abc", "bag", "Boom", "great"}。当我在地图中添加它们时,我得到了

Abc 1 Boom 1 abc 1 bag 1 great 1

但预期的结果是

Abc 1 abc 1 Boom 1 bag 1 great 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;
}

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

【问题讨论】:

  • 欢迎来到 Stackoverflow。你的排序问题到底是什么?你试过什么了。作为一般规则,这里更具体的问题会吸引更高质量的回复。
  • 您也可以尝试格式化您的代码以使用空格来使块真正明显。这有助于思考代码,也有助于其他人更快地理解代码。
  • std::map 已经使用operator&lt; 进行了排序,因此它们已经按照您想要的顺序排列。你有什么问题?
  • 我已经阅读并添加到地图中 -- 现在遍历你的地图从map.begin()map.end() 并查看@987654328 的first @ 映射的每个元素。瞧,数据已排序。

标签: c++


【解决方案1】:

OP 想要一个与标准字典顺序略有不同的自定义排序顺序。一个带有自定义排序顺序的map可以通过传入一个自定义的Compare来实现(Comparemap的第三个模板参数):

#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&lt;key&gt;(在本例中为less&lt;string&gt;),它将按照标准词典A-z 顺序对字符串进行排序。

【讨论】:

    【解决方案2】:

    这是一个包含文件读取的完整示例,并使用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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2019-01-07
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      相关资源
      最近更新 更多