Merge two maps, summing values for same keys in C++

后端 未结 3 1616
遇见更好的自我
遇见更好的自我 2021-02-07 22:20

I have two std::map maps and wish to merge them into a third map like this: if the same key is found in both maps, create a pair in the third map wi

3条回答
  •  死守一世寂寞
    2021-02-07 22:47

    An overly generic solution inspired by std::set_union. Unlike the first suggested answer, this should run in O(n) instead of O(n log n).

    Edit: it's still O(n log n) because of insertions into the final map.

    #include 
    #include 
    #include 
    #include 
    
    template
    OutputIterT merge_apply(
        InputIterT1 first1, InputIterT1 last1,
        InputIterT2 first2, InputIterT2 last2,
        OutputIterT result, Comparator comp, Func func) {
      while (true)
      {
        if (first1 == last1) return std::copy(first2, last2, result);
        if (first2 == last2) return std::copy(first1, last1, result);
    
        if (comp(*first1, *first2) < 0) {
          *result = *first1;
          ++first1;
        } else if (comp(*first1, *first2) > 0) {
          *result = *first2;
          ++first2;
        } else { 
          *result = func(*first1, *first2);
          ++first1;
          ++first2; 
        }   
        ++result;
      }
    }
    
    template
    int compare_first(T a, T b) {
      return a.first - b.first;
    }
    
    template
    T sum_pairs(T a, T b) {
      return std::make_pair(a.first, a.second + b.second);
    }
    
    using namespace std;
    int main(int argc, char **argv) {
      map a,b,c;
    
      a[1] = 10; 
      a[2] = 11; 
    
      b[2] = 100;
      b[3] = 101;
    
      merge_apply(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.begin()),
          compare_first >, sum_pairs >); 
    
      for (auto item : c)                                                                                                       
        cout << item.first << " " << item.second << endl;
    }
    

提交回复
热议问题