如何在输入中找到最常见的数字?

时间:2010-09-04 15:22:01

标签: c++

这是我正在做的非常抽象的解释:

假设我有一个由换行符分隔的数字文本文件。现在,我把这些数字放在map<int, int>中,其中键是数字,值是频率。

我的最终目标是按频率排序的数字列表。我该怎么做呢?请注意,频率显然可以出现多次。我想的方法是使struct包含一个数字及其频率,并定义<以便它永远不会返回相等。然后我会遍历地图,将所有元素放入该结构中,然后放入集合中。

3 个答案:

答案 0 :(得分:8)

一旦你构建了频率图,将它的对复制到std::vector<std::pair<int, int> >,然后std::sort将后者复制到std::sort的3-args版本,将比较器作为第三个ARG;作为比较器,您可以使用首先比较对.second字段的字段和.first字段(如果需要),仅消除.second字段为{{1}}字段的对的排序相等(但我不认为你真的需要最后一点,因为你不关心频率相等的情况的排序,对吗?)。

答案 1 :(得分:1)

如果这只是你想要自己做的操作(而不是你想要使用的组件),对我来说最实用的方法就是做这样的事情:

sort <filename> | uniq -c | sed 's/^[ \t]*//' | sort -rn

当然,与线性算法相比,它不能很好地扩展,但它对于每天的任务都表现得相当好,而且它还有一个额外的好处,就是你不需要自己重新发明轮子。


编辑:排序“对您的文件进行排序;”uniq“将所有相同的连续行分组到一对[频率] [项]对中,例如

12
12
24
25
25
25

变为

    2 12
    1 24
    3 25

然后我用“sed”删除尾随空格(如果这不起作用,这是因为有时候输入制表符的方式有问题),然后我根据频率对输出进行排序(“ n“选项要求进行数字排序,而不是字典;”r“选项要求进行反向排序。

如果要为排序选择另一个字段(例如,因为您实际想要计算频率的数字是制表符分隔线的THIRD字段),那么您可以使用“排序”的选择功能:

sort -t'\t' -k3 <filename> | ...

这表示您的输入是制表符分隔的字段列表,并且您希望根据第三个字段进行排序。


编辑2 :这是根据第四个字段执行此操作的行(并删除所有其他字段)

cut -d'\t' -f4 <filename> | sort | uniq -c | sed 's/^[ \t]*//' | sort -rn

答案 2 :(得分:0)

迭代std:pair的{​​{1}}并将其插入std::map。使用值中的比较函数。

获得优先级队列后,您可以迭代它。