set_difference Алгоритм дает вывод элементов, которые находятся в первом диапазоне, а не во втором. Есть ли алгоритм, который просто даст мне счет, а не разницу.
Я понимаю, что могу реализовать свою собственную версию алгоритма, описанного в ссылке, или подсчитать количество элементов после получения результата. Есть ли существующий API, который сделает это для меня эффективно.
Спасибо
Вы могли бы просто написать свою собственную подобную OutputIterator вещь, которую вы могли бы передать std::set_difference
, OutputIterator должен быть разыменовываемым, присваиваемым и увеличиваемым. Обратите внимание, что std::set_difference
возвращает OutputIterator, поэтому мы можем воспользоваться этим, сделав его конвертируемым в int
,
Отсюда что-то вроде:
struct CountingIterator
: std::iterator<std::output_iterator_tag, int>
{
template <typename T>
CountingIterator& operator=(T&& ) {
++count;
return *this;
}
CountingIterator& operator*() { return *this; }
CountingIterator& operator++() { return *this; }
operator int() { return count; }
int count = 0;
};
Который, изменяя пример в std::set_difference
выходы:
int main() {
std::vector<int> v1 {1, 2, 5, 5, 5, 9};
std::vector<int> v2 {2, 5, 7};
int count =
std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
CountingIterator());
std::cout << count << std::endl; // prints 4
}
Это такая тривиальная операция, которая не требует определенного метода. Если вы не можете позволить себе выделить временный набор для вычисления разницы, а затем получить их размер, просто рассчитайте его с помощью std::accumulate
или же std::for_each
:
unordered_set<int> set1 = {1,2,3,4,5};
unordered_set<int> set2 = {2,4,6};
size_t count = set1.size() - std::accumulate(set1.begin(), set1.end(), 0, [&set2](size_t previous, int value) { return set2.count(value) + previous; });
Но если у вас нет особых требований или огромных сетов, делающих set_difference
+ size()
это просто хорошо.
Вы можете создатьCountingIterator
» как OutputIterator
, что-то вроде:
struct CountingIterator
{
CountingIterator& operator*() { return *this; }
CountingIterator& operator ++() { return *this; }
CountingIterator& operator ++(int) { return *this; }
template <typename T>
CountingIterator& operator =(const T&) { ++counter; return *this; }
int counter = 0;
};