2012-06-15 7 views
5

要素を発生回数でソートしたいのですが、 これは私が出ているものです(mHeightsはstd ::多重集合である):その後、私はそれらをカウントし、(新しいコンテナに私をそれらを並べ替える私は、マルチセットからすべてのユニークな要素を取るので、最初要素の出現数でコンテナにマルチセットを並べ替える方法

namespace{ 
    template<class U,class T> 
    class HistPair{ 
    public: 
     HistPair(U count,T const& el):mEl(el),mNumber(count){  
     } 
     T const& getElement()const{return mEl;} 

     U getCount()const{return mNumber;} 
    private: 
     T mEl; 
     U mNumber; 
    }; 

    template<class U,class T> 
    bool operator <(HistPair<U,T> const& left,HistPair<U,T> const& right){ 
    return left.getCount()< right.getCount(); 
    } 
} 

std::vector<HistPair<int,double> > calcFrequentHeights(){ 
    typedef HistPair<int,double> HeightEl; 
    typedef std::vector<HistPair<int,double> > Histogram; 
    std::set<double> unique(mHeights.begin(),mHeights.end()); 
    Histogram res; 
    boostForeach(double el, unique) { 
    res.push_back(HeightEl(el,mHeights.count(el)));  
    } 
    std::sort(res.begin(),res.end()); 
    std::reverse(res.begin(),res.end()); 
    return res; 
} 

私はマップを使用するようにカウントが必要です)。このような簡単な作業では、これはかなり複雑に見えます。 他の場所でも使用されているHistPairは別として、このタスクを簡略化するstlアルゴリズムはありません。 equal_rangeまたはsthを使用します。似ている。

編集:私はこのスニペットその

+1

が私にはかなり簡潔ルックス。あなたのヒストグラム作成ルーチンから2行以上を計画しているとは想像できません。代わりに、 'std :: multiset 'の代わりに 'std :: map 'を使い、要素を挿入するときにビンサイズを決めることもできますが、それほど変わることはありません。 – Rook

+0

@nims:それは私がやっていることですか、私はあなたを誤解しました。私はカウントと要素が必要です – Martin

+0

@マーティン私の悪い、それを見落とした。 – nims

答えて

6

忘れて申し訳ありませんが、ラムダとstd::multiset::countstd::setを組み合わせることにより、あなたが欲しいものを行い、同様に出現箇所の数が必要になります。

#include <iostream> 
#include <set> 
#include <vector> 
#include <algorithm> 

int main() { 
    std::multiset<int> st; 
    st.insert(12); 
    st.insert(12); 
    st.insert(12); 
    st.insert(145); 
    st.insert(145); 
    st.insert(1); 
    st.insert(2); 

    std::set<int> my_set(st.begin(), st.end()); 
    std::vector<int> my_vec(my_set.begin(), my_set.end()); 
    std::sort(my_vec.begin(), my_vec.end(), 
     [&](const int &i1, const int &i2) { 
      return st.count(i1) < st.count(i2); 
     } 
    ); 

    for(auto i : my_vec) { 
     std::cout << i << " "; 
    } 
    std::cout << std::endl; 
} 

にあなたは可能性がありますベクトルを逆にしたい。この出力:

1 2 145 12 

編集:あなたもアイテム数を必要考慮すると、これはそれを行います。

出力
#include <iostream> 
#include <set> 
#include <vector> 
#include <algorithm> 

int main() { 
    typedef std::vector<std::pair<int, int>> MyVector; 
    std::multiset<int> st; 
    st.insert(12); 
    st.insert(12); 
    st.insert(12); 
    st.insert(145); 
    st.insert(145); 
    st.insert(1); 
    st.insert(2); 

    std::set<int> my_set(st.begin(), st.end()); 
    MyVector my_vec; 
    my_vec.reserve(my_set.size()); 

    for(auto i : my_set) 
     my_vec.emplace_back(i, st.count(i)); 

    std::sort(my_vec.begin(), my_vec.end(), 
     [&](const MyVector::value_type &i1, const MyVector::value_type &i2) { 
      return i1.second < i2.second; 
     } 
    ); 

    for(const auto &i : my_vec) 
     std::cout << i.first << " -> " << i.second << std::endl; 
} 

1 -> 1 
2 -> 1 
145 -> 2 
12 -> 3 
+0

ありがとうございます。ラムダはちょっと便利です;-)しかし、私もカウントが必要であることを忘れていましたが、これはあなたのソリューションに統合するのが難しいはずはありません – Martin

+0

あなたは、私の答えを編集しました。 – mfontanini

+0

もう一度ありがとう! – Martin

関連する問題