#include <cassert>
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
// Do not call this method if you have a single set...
// And the pointers better not be null either!
std::vector<int> intersect(std::vector< std::set<int> const* > const& sets) {
for (auto s: sets) { assert(s && "I said no null pointer"); }
std::vector<int> result; // only return this one, for NRVO to kick in
// 0. Check obvious cases
if (sets.empty()) { return result; }
if (sets.size() == 1) {
result.assign(sets.front()->begin(), sets.front()->end());
return result;
}
// 1. Merge first two sets in the result
std::set_intersection(sets[0]->begin(), sets[0]->end(),
sets[1]->begin(), sets[1]->end(),
std::back_inserter(result));
if (sets.size() == 2) { return result; }
// 2. Merge consecutive sets with result into buffer, then swap them around
// so that the "result" is always in result at the end of the loop.
std::vector<int> buffer; // outside the loop so that we reuse its memory
for (size_t i = 2; i < sets.size(); ++i) {
buffer.clear();
std::set_intersection(result.begin(), result.end(),
sets[i]->begin(), sets[i]->end(),
std::back_inserter(buffer));
swap(result, buffer);
}
return result;
}
int main() {
std::set<int> x = {1, 2, 3};
std::set<int> y = {1, 3, 4};
auto result = intersect({&x, &y});
std::cout << result.size() << ": " << result[0] << ", " << result[1] << "\n";
}
I2luY2x1ZGUgPGNhc3NlcnQ+CgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDx2ZWN0b3I+CgovLyBEbyBub3QgY2FsbCB0aGlzIG1ldGhvZCBpZiB5b3UgaGF2ZSBhIHNpbmdsZSBzZXQuLi4KLy8gQW5kIHRoZSBwb2ludGVycyBiZXR0ZXIgbm90IGJlIG51bGwgZWl0aGVyIQpzdGQ6OnZlY3RvcjxpbnQ+IGludGVyc2VjdChzdGQ6OnZlY3Rvcjwgc3RkOjpzZXQ8aW50PiBjb25zdCogPiBjb25zdCYgc2V0cykgewogICAgZm9yIChhdXRvIHM6IHNldHMpIHsgYXNzZXJ0KHMgJiYgIkkgc2FpZCBubyBudWxsIHBvaW50ZXIiKTsgfQoKICAgIHN0ZDo6dmVjdG9yPGludD4gcmVzdWx0OyAvLyBvbmx5IHJldHVybiB0aGlzIG9uZSwgZm9yIE5SVk8gdG8ga2ljayBpbgoKICAgIC8vIDAuIENoZWNrIG9idmlvdXMgY2FzZXMKICAgIGlmIChzZXRzLmVtcHR5KCkpIHsgcmV0dXJuIHJlc3VsdDsgfQoKICAgIGlmIChzZXRzLnNpemUoKSA9PSAxKSB7CiAgICAgICAgcmVzdWx0LmFzc2lnbihzZXRzLmZyb250KCktPmJlZ2luKCksIHNldHMuZnJvbnQoKS0+ZW5kKCkpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgoKICAgIC8vIDEuIE1lcmdlIGZpcnN0IHR3byBzZXRzIGluIHRoZSByZXN1bHQKICAgIHN0ZDo6c2V0X2ludGVyc2VjdGlvbihzZXRzWzBdLT5iZWdpbigpLCBzZXRzWzBdLT5lbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRzWzFdLT5iZWdpbigpLCBzZXRzWzFdLT5lbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmJhY2tfaW5zZXJ0ZXIocmVzdWx0KSk7CgogICAgaWYgKHNldHMuc2l6ZSgpID09IDIpIHsgcmV0dXJuIHJlc3VsdDsgfQoKCiAgICAvLyAyLiBNZXJnZSBjb25zZWN1dGl2ZSBzZXRzIHdpdGggcmVzdWx0IGludG8gYnVmZmVyLCB0aGVuIHN3YXAgdGhlbSBhcm91bmQKICAgIC8vICAgIHNvIHRoYXQgdGhlICJyZXN1bHQiIGlzIGFsd2F5cyBpbiByZXN1bHQgYXQgdGhlIGVuZCBvZiB0aGUgbG9vcC4KCiAgICBzdGQ6OnZlY3RvcjxpbnQ+IGJ1ZmZlcjsgLy8gb3V0c2lkZSB0aGUgbG9vcCBzbyB0aGF0IHdlIHJldXNlIGl0cyBtZW1vcnkKCiAgICBmb3IgKHNpemVfdCBpID0gMjsgaSA8IHNldHMuc2l6ZSgpOyArK2kpIHsKICAgICAgICBidWZmZXIuY2xlYXIoKTsKCiAgICAgICAgc3RkOjpzZXRfaW50ZXJzZWN0aW9uKHJlc3VsdC5iZWdpbigpLCByZXN1bHQuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHNbaV0tPmJlZ2luKCksIHNldHNbaV0tPmVuZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmJhY2tfaW5zZXJ0ZXIoYnVmZmVyKSk7CgogICAgICAgIHN3YXAocmVzdWx0LCBidWZmZXIpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCmludCBtYWluKCkgewoJc3RkOjpzZXQ8aW50PiB4ID0gezEsIDIsIDN9OwoJc3RkOjpzZXQ8aW50PiB5ID0gezEsIDMsIDR9OwoJCglhdXRvIHJlc3VsdCA9IGludGVyc2VjdCh7JngsICZ5fSk7CgkKCXN0ZDo6Y291dCA8PCByZXN1bHQuc2l6ZSgpIDw8ICI6ICIgPDwgcmVzdWx0WzBdIDw8ICIsICIgPDwgcmVzdWx0WzFdIDw8ICJcbiI7Cn0=