C ++,基于第二个iter订购地图内容

时间:2012-08-07 14:02:54

标签: c++ string iterator int

我的地图如下

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-&gt;第二个值来显示地图。

我该怎么做?

3 个答案:

答案 0 :(得分: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));
    }
}

答案 1 :(得分:1)

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

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

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"以外的属性,则原始输出和此例程会丢失该关联,并且您只会获得与外部字相关联的多个数字。

答案 2 :(得分:0)

如果您愿意使用Boost,则可以使用Boost::Bimap,这样您就可以将单词与计数相关联,并使用单词计数(同时)。这个example显示了如何计算文本的字数并显示直方图。

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


为了完整起见,我将添加另一个使用heapsort的解决方案,方法是通过std::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();
    }
}