【问题标题】:Sorting a map with unknown keys by value按值对具有未知键的地图进行排序
【发布时间】:2014-04-22 10:59:20
【问题描述】:

我有一张如下风格的地图:

mapa["01"]=2
mapa["111"]=3

显示每个子字符串在文本中出现的频率(文本由 1 和 0 组成)。

现在假设我要输出 10 个最常用的子字符串,我需要遍历 map 中的所有键并获取具有最大值的键(按值排序,降序)。我应该使用任何伪代码或命令吗?

如果它对你有用,我正在处理this 任务并且我得到了所有值,我只是不知道如何对它们进行排序。

【问题讨论】:

  • 如果这是您希望对数据执行的唯一项操作,则说明您存储错误。 :)
  • @LightnessRacesinOrbit 是否愿意提出任何其他想法?请记住,我在这里仍然是初学者,解决高中比赛的任务。也不能使用额外的库。
  • @LightnessRacesinOrbit 我不同意。这基本上是最常见元素的常见 map-reduce 解决方案。 map(text)->(token,'1'), reduce(token,list)->(token,sum(list),然后选择top k。唯一值得注意的区别是使用基于树的地图而不是散列解决方案(这就是 MR 的实现方式)
  • @amit:如果这是他想要执行的唯一查找,那么他的键和值显然是错误的。如果没有,那么没有问题。
  • @LightnessRacesinOrbit 该地图是他在上一步中创建的直方图。他必须计算每个子字符串的#occurrances,这就是通常的做法。

标签: c++ algorithm sorting map


【解决方案1】:

你基本上需要使用比较器实现一些top-k过滤算法

x < y if and only if mapa[x] < mapa[y]

线程Store the largest 5000 numbers from a stream of numbers中涵盖了有效地从列表中选择前k个:

基本思想是创建一个最小堆,它始终存储迄今为止遇到的前 k 个元素。完成后,堆包含流中的前 K 个元素。

另一种方法是使用选择算法找到第 10 个最大的元素,并生成所有大于它的元素(如果有重复则工作量更大)。

【讨论】:

    【解决方案2】:

    看到这个duplicate,你基本上是迭代地图并在值上使用std::partial_sort。

    typedef std::pair<std::string, int> mypair;
    
    struct IntCmp {
        bool operator()(const mypair &lhs, const mypair &rhs) {
            return lhs.second > rhs.second;
        }
    };
    
    
    void print10(const std::map<std::string,int> &mymap) {
        std::vector<mypair> myvec(mymap.begin(), mymap.end());
        assert(myvec.size() >= 10);
        std::partial_sort(myvec.begin(), myvec.begin() + 10, myvec.end(), IntCmp());
    
        for (int i = 0; i < 10; ++i) {
            std::cout << i << ": " << myvec[i].first 
                << "-> " << myvec[i].second << "\n";
        }
    }
    

    【讨论】:

    • 有效,但amit的解决方案更好(无需复制绝对不在前10名的地图条目)
    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 2015-04-06
    • 2012-04-25
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    相关资源
    最近更新 更多