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編集:代わりにペアの a を使用することで、必要な二重ソートを取得できると思います:

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

に挿入して、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"している場合、元の出力とこのルーチンはその関連付けを失い、外側の単語に関連付けられた複数の数値を取得するだけです。

于 2012-08-07T14:35:05.933 に答える
0

Boost の使用を受け入れる場合は、 Boost::Bimapを使用できます。これにより、単語をカウントに関連付け、カウントを単語に (同時に) 関連付けることができます。このでは、テキストの単語数を計算し、ヒストグラムを表示する方法を示します。

ソートされた単語数をときどき表示するだけでよい場合は、通常std::mapの単語数マップを使用する方が高速な場合があります。次に、他の回答に示されている手法を使用して、必要に応じて並べ替えられた単語数を生成します。どちらが速いかを知るには、おそらくベンチマークを実行する必要があります。


完全を期すために、マップのペアをプッシュして、出現順に並べ替えられた単語数を取得することで、ヒープソートを使用する別のソリューションを追加します。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();
    }
}
于 2012-08-07T14:51:42.263 に答える