7

我有如下地图

string word;
int occurance;
std::map< std::string, std::map<string, int> > map;
map[word]["count"] = occurance;

使用迭代器映射输出。

for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
        for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) {
            std::cout << outer_iter->first << '\t'  << inner_iter->second << std::endl;
        }
    }

我想通过订购 inner_iter->second 值来显示地图。

我该怎么做?

4

3 回答 3

5

最简单的使用方法(除非分析另有说明)是在需要打印时简单地制作一张由内向外的地图:

std::multimap<int, std::string> inverse_map;

for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter)
{
    for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter)
    {
        inverse_map.insert(std::make_pair(inner_iter->second, outer_iter->first));
    }
}

然后你只需遍历倒置的地图并正常打印。

编辑:我认为你可以通过使用一set对来获得你想要的双重排序:

std::set<std::pair<int, std::string> > inverse_map;

for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter)
{
    for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter)
    {
        inverse_map.insert(std::make_pair(inner_iter->second, outer_iter->first));
    }
}
于 2012-08-07T14:25:48.743 回答
1

您可以插入 avector并相应地对内容进行排序。

编辑:修改为从最高到最低排序。

typedef std::pair<std::string, int> hist_item;
std::vector<hist_item> hist;
hist.reserve(map.size());

for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
    for(auto inner_iter=outer_iter->second.begin();
        inner_iter!=outer_iter->second.end(); ++inner_iter) {
        hist.push_back(std::make_pair(outer_iter->first, inner_iter->second));
    }
}
std::sort(hist.begin(), hist.end(),
          [](const hist_item &a,const hist_item &b){return a.second>b.second;});
for (auto i = hist.begin(); i!= hist.end(); ++i) {
    std::cout << i->first << '\t' << i->second << std::endl;
}

这模仿了您的原始输出。我不确定内部地图的用途。如果您正在跟踪其中以外"count"的属性,则您的原始输出和此例程会失去该关联,并且您只会获得与外部单词关联的多个数字。

于 2012-08-07T14:35:05.933 回答
0

如果您愿意使用 Boost,则可以使用Boost::Bimap,它可以让您将单词与计数相关联,并将计数与单词(同时)相关联。此示例说明如何计算文本的字数并显示直方图。

如果您只需要偶尔显示排序后的字数,使用正则std::map来构建字数图可能会更快。然后,您可以使用其他答案中显示的技术根据需要生成排序的字数。您可能必须运行基准测试才能知道哪个更快。


为了完整起见,我将添加另一个使用堆排序的解决方案,方法是将映射对推送到 astd::priority_queue以获得按出现排序的字数:

#include <iostream>
#include <map>
#include <queue>

typedef std::map<std::string, int> MyMap;

struct OrderByOccurence
{
    bool operator()(MyMap::const_reference lhs, MyMap::const_reference rhs)
    {
        // This will make the priority queue sort from highest word count
        // to lowest.
        return lhs.second < rhs.second;

        // This will make the priority queue sort from lowest word count
        // to highest.
        // return rhs.second < lhs.second;

        // Here, you can also check that if both counts are the same,
        // the elements should be ordered alphabetically by word.
    }
};

int main()
{
    MyMap m = {{"a", 1}, {"b", 2}, {"c", 3}};

    std::priority_queue<std::pair<std::string, int>,
                        std::vector< std::pair<std::string, int> >,
                        OrderByOccurence> q;
    for (auto it=m.begin(); it!=m.end(); ++it)
        q.push(*it);

    while (!q.empty())
    {
        std::cout << q.top().first << " " << q.top().second << "\n";
        q.pop();
    }
}
于 2012-08-07T14:51:42.263 回答