2008-10-29 16 views
31

मल्टीमैप में अनिवार्य रूप से कुंजी द्वारा क्रमबद्ध डेटा के समूह हैं। मुझे एक तरीका चाहिए जिसके द्वारा मैं इन व्यक्तिगत समूहों तक पहुंच सकता हूं और उनके कुल मूल्य प्राप्त कर सकता हूं। उदाहरण के लिए, एक std::multimap< string, int > में मैंstl :: multimap - मैं डेटा के समूह कैसे प्राप्त करूं?

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

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

स्टोर इन मूल्यों को संग्रहीत करने के बाद, मैं इस मल्टीमैप पुनरावृति और प्रत्येक "समूह" का कुल मूल्यों को प्राप्त करने के लिए सक्षम होना चाहिए। समस्या यह है कि इस तरह से मल्टीमैप्स तक पहुंचने के लिए एसटीएल में परिभाषित कोई भी कार्य नहीं है। मैन्युअल रूप से मल्टीमैप को पुन: सक्रिय करने और समूह की सामग्री को कुल करने के लिए मैं lower_bound, upper_bound का उपयोग कर सकता हूं, लेकिन मुझे आशा है कि एसटीएल में पहले से परिभाषित बेहतर तरीके हो सकते हैं? क्या कोई इस बात का समाधान कर सकता है कि उपरोक्त उदाहरण में समूह के लिए मैं कुल मूल्य कैसे प्राप्त कर सकता हूं।

+0

बहुत ही सुंदर और लैम्बडा विधि यहां वर्णित है: http://stackoverflow.com/a/37680747/5516759 –

उत्तर

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

एक तरीका है।

संपादित करें:

समूह आप देख रहे हैं पता नहीं है, और बस प्रत्येक समूह के माध्यम से जा रहे हैं, अगले समूह की सीमा हो रही इतनी तरह किया जा सकता है:

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>()); 
+0

यह 'x.first == y.first;' नहीं होना चाहिए? आपने 'ऑपरेटर <' का उपयोग क्यों किया है? [Document] (http://www.cplusplus.com/reference/algorithm/adjacent_find/) के अनुसार 'adjacent_find' के अनुसार, पूर्वानुमान पैरामीटर को तुलना के परिणाम को वास्तविक (गैर-शून्य) के साथ वापस करना चाहिए जिसका अर्थ है कि वे हैं बराबर के लिए बराबर, और झूठी (शून्य) माना जाना चाहिए। गैर-बराबर परिणाम के लिए आप सच क्यों लौट रहे हैं? – Meysam

+2

हां, यह एक गलती प्रतीत होता है। 'adjacent_find' एक" बराबर "भविष्यवाणी की अपेक्षा करता है। साथ ही, मुझे यकीन है कि 'std :: equal_to ' उपयोग करने के लिए तैयार है। – leemes

+0

@leemes मुझे विश्वास है कि आपका संपादन गलत व्यवहार को बदल देता है। कुंजी से पहले "कम से कम" ऑपरेटर को अंतिम तत्व मिलना था (जिसे नई कुंजी के साथ पहले तत्व में 1 तक अग्रिम 'किया जा सकता था), जबकि समानता ऑपरेटर के साथ यह केवल इटरेटर को उसी पर वापस कर देगा ('पहले ') तत्व – slawekwin

10

यदि आप पहले से ही चाबियाँ जानते हैं, तो आप समूह की शुरुआत और अंत में इटरेटर प्राप्त करने के लिए multimap::equal_range का उपयोग कर सकते हैं; सीमा से वांछित परिणाम प्राप्त करने के लिए किसी भी मानक एल्गोरिदम का उपयोग करें। यदि आप चाबियाँ नहीं जानते हैं, तो आप begin() पर शुरू कर सकते हैं और प्रत्येक नए समूह की शुरुआत को खोजने के लिए कुंजी की तुलना करके स्वयं को फिर से चला सकते हैं।

-1

कोई मल्टीमैप उत्तर नहीं है, लेकिन यदि आप चुनते हैं तो आप निम्न की तरह चीजें कर सकते हैं।

#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"; 
     } 
    } 
} 
1

आप एक वैकल्पिक कंटेनर का उपयोग कर सकते हैं जिसमें प्रत्येक समूह की कुल रकम हो सकती है। यदि आप लैम्ब्डा की राशि (C++ 0x में)

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 

बेशक, यह आसान हो सकता है: ऐसा करने के लिए आप की तरह कुछ कर सकता

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; 
    } 
); 
19
// 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 
+1

पर अंतिम संपादन वापस ले लिया है यह भी देखें: http://stackoverflow.com/a/9371314/19501 –

0
equal_range 
Syntax:  
#include <map> 
pair<iterator, iterator> equal_range(const key_type& key); 
The function equal_range() returns two iterators - one to the first 
element that contains key, another to a point just after the last 
element that contains key. 
संबंधित मुद्दे