Frage

Multimap hat im wesentlichen Gruppen von durch den Schlüssel sortierte Daten. Ich möchte ein Verfahren, mit dem ich diese einzelnen Gruppen zugreifen können und deren Gesamtwerte erhalten. Zum Beispiel in einem std::multimap< string, int > I store

{"Group1", 1}, 
{"Group1", 2}, 
{"Group1", 3}, 

{"Group2", 10}, 
{"Group2", 11}, 
{"Group2", 12}

diese Werte gespeichert wurden, sollte ich in der Lage sein, diese multimap iterieren und die aggregierten Werte jeder „Gruppe“ bekommen. Das Problem ist, es gibt keine Funktionen in AWL definiert MultiMaps so zuzugreifen. Ich konnte lower_bound, upper_bound verwenden, um manuell die multimap laufen und insgesamt den Inhalt der Gruppe, aber ich hoffe es schon bessere Möglichkeiten in STL definiert sein könnte? Kann mir jemand eine Lösung vorzuschlagen, wie ich die Gesamtwerte für eine Gruppe in dem obigen Beispiel erhalten könnte.

War es hilfreich?

Lösung

pair<Iter, Iter> range = my_multimap.equal_range("Group1");
int total = accumulate(range.first, range.second, 0);

ist eine Möglichkeit.

Edit:

Wenn Sie nicht wissen, die Gruppe die Sie suchen, und sind nur durch jede Gruppe gehen, bekommen die Reichweite der nächsten Gruppe kann wie so getan werden:

template <typename Pair>
struct Less : public std::binary_function<Pair, Pair, bool>
{
    bool operator()(const Pair &x, const Pair &y) const
    {
        return x.first < y.first;
    }
};

Iter first = mmap.begin();
Iter last = adjacent_find(first, mmap.end(), Less<MultimapType::value_type>());

Andere Tipps

// samekey.cpp -- Process groups with identical keys in a multimap

#include <iostream>
#include <string>
#include <map>
using namespace std;

typedef multimap<string, int> StringToIntMap;
typedef StringToIntMap::iterator mapIter;

int main ()
{
    StringToIntMap mymap;

    mymap.insert(make_pair("Group2", 11));
    mymap.insert(make_pair("Group1",  3));
    mymap.insert(make_pair("Group2", 10));
    mymap.insert(make_pair("Group1",  1));
    mymap.insert(make_pair("Group2", 12));
    mymap.insert(make_pair("Group1",  2));

    cout << "mymap contains:" << endl;

    mapIter m_it, s_it;

    for (m_it = mymap.begin();  m_it != mymap.end();  m_it = s_it)
    {
        string theKey = (*m_it).first;

        cout << endl;
        cout << "  key = '" << theKey << "'" << endl;

        pair<mapIter, mapIter> keyRange = mymap.equal_range(theKey);

        // Iterate over all map elements with key == theKey

        for (s_it = keyRange.first;  s_it != keyRange.second;  ++s_it)
        {
           cout << "    value = " << (*s_it).second << endl;
        }
    }

    return 0;

}   //  end main

// end samekey.cpp

Wenn Sie bereits die Schlüssel kennen, können Sie verwenden, um die multimap::equal_range Iteratoren zu Beginn und am Ende der Gruppe zu erhalten; Verwenden Sie einen beliebigen Standard-Algorithmus die gewünschten Ergebnisse aus dem Bereich zu erhalten. Wenn Sie nicht über die Schlüssel kennen, können Sie bei begin() starten und durchlaufen sie selbst, Schlüssel Vergleichen der Beginn jeder neuen Gruppe zu finden.

Sie können einen alternativen Behälter verwenden, die die Gesamtsummen der einzelnen Gruppen enthalten kann. Um dies zu tun, man könnte so etwas tun:

template <class KeyType, class ValueType>
struct group_add {
  typedef map<KeyType, ValueType> map_type;
  map_type & aggregates;
  explicit group_add(map_type & aggregates_)
    : aggregates(aggregates_) { };
  void operator() (map_type::value_type const & element) {
    aggregates[element.first] += element.second;
  };
};

template <class KeyType, class ValueType>
group_add<KeyType, ValueType>
make_group_adder(map<KeyType, ValueType> & map_) {
  return group_add<KeyType, ValueType>(map_);
};

// ...
multimap<string, int> members;
// populate members
map<string, int> group_aggregates;
for_each(members.begin(), members.end(),
  make_group_adder(group_aggregates));
// group_aggregates now has the sums per group

Natürlich, wenn Sie Lambda ist (in C ++ 0x) es könnte einfacher sein:

multimap<string, int> members;
map<string, int> group_aggregates;
for_each(members.begin(), members.end(),
  [&group_aggregates](multimap<string, int>::value_type const & element) {
    group_aggregates[element.first] += element.second;
  }
  );
equal_range

Syntax:

#include <map>
pair<iterator, iterator> equal_range( const key_type& key );

Die Funktion equal_range() gibt zwei Iteratoren - ein auf das erste Element, das Schlüssel enthält, die andere zu einem Punkt unmittelbar nach dem letzten Element Schlüssel enthält.

Kein multimap Antwort, aber man kann die Dinge tun, wie folgt aus, wenn Sie so wählen.

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
using namespace std;
using namespace boost;
using namespace boost::assign;

int main() {
    typedef map<string, vector<int> > collection;
    collection m;
    m["Group 1"] = list_of(1)(2)(3);
    m["Group 2"] = list_of(10)(11)(12);
    collection::iterator g2 = m.find("Group 2");
    if (g2 != m.end()) {
        BOOST_FOREACH(int& i, g2->second) {
            cout << i << "\n";
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top