获得两个类型map容器之间差异的最佳方法< classId,set< studentId> >

时间:2013-12-04 08:50:09

标签: c++ stl

我有以下两个容器

map <classId, set< studentId> > allStudents;
map <classId, set< studentId> > assocStudents;

其中,assocStudents是所有学生的子集。 获得所有学生减去assocStudents以获得unassocStudents的最有效方法是什么?

map <classId, set< studentId> > unassocStudents;

我能想到的最好的是

  1. 遍历所有学生中的每个班级,在assocStudents中搜索该classId。
  2. 如果该类存在于assocStudents中,请执行studentId的set_difference;
  3. 否则复制整个studentId集。
  4. 有更聪明的方法吗?

    编辑:

    我对所提供的答案感到有些失落。

    假设我有以下数据

     allStudents contains classId 1, studentId {1, 11, 111, 1111}
                          classId 2, studentId (2, 22, 222, 2222}
     assocStudents contains classId 2, studentId {22, 2222}
    

    我喜欢最终的容器

     unassocStudents contains classId 1, studentId {1, 11, 111, 1111}
                              classId 2, studentId (2, 222}
    

    不会set_difference给我以下

     unassocStudents contains classId 1, studentId {1, 11, 111, 1111}
    

3 个答案:

答案 0 :(得分:3)

只需使用std::set_difference

即可
#include  <iterator>

std::set_difference(allStudents.begin(), allStudents.end(), 
            assocStudents.begin(), assocStudents.end(),
            std::inserter(unassocStudents, unassocStudents.end()));

答案 1 :(得分:1)

这为您提供了所需的答案:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <set>

using classId = int;
using studentId = int;
using map = std::map<classId, std::set<studentId>>;

int main()
{
    map allStudents{
        {1, {1, 11, 111, 1111}},
        {2, {2, 22, 222, 2222}},
    };
    map assocStudents{
        {2, {22, 2222}},
    };
    map unassocStudents;

    // Setup keys.
    for (auto const& i : allStudents) {
        auto& unassocSet = unassocStudents[i.first];
        auto& assocSet = assocStudents[i.first];
        std::set_difference(i.second.begin(), i.second.end(),
                            assocSet.begin(), assocSet.end(),
                            std::inserter(unassocSet, unassocSet.end()));
    }

    for (auto const& i : unassocStudents) {
        std::cout << "classId = " << i.first << '\n';
        for (auto const j : i.second) {
            std::cout << "\tstudentId = " << j << '\n';
        }
    }
}

See it working here

答案 2 :(得分:0)

对于那些感兴趣的人。 以下是@ Simple解决方案的C ++ 98实现

typedef map<int, set <long> > csMap;
for (csMap::const_iterator i = allStudents.begin(); i!=allStudents.end(); ++i){

    set<long>& assocSet = assocSet[i->first];
    set<long>& unassocSet = unassocSet[i->first];

    set_difference (i->second.begin(), i->second.end(),
                    assocSet.begin(), assocSet.end(),
                    inserter(unassocSet, unassocSet.end()));

    if (unassocSet.empty()) { unassoc.erase( i->first);}
    if (assocSet.empty()) { assoc.erase( i->first);}

}

@ simple的C ++ 11解决方案

// Setup keys.
for (auto const& i : allStudents) {
    auto& unassocSet = unassocStudents[i.first];
    auto& assocSet = assocStudents[i.first];
    std::set_difference(i.second.begin(), i.second.end(),
                        assocSet.begin(), assocSet.end(),
                        std::inserter(unassocSet, unassocSet.end()));
}