Подсчитайте количество элементов, отличающихся в одном наборе от другого

set_difference Алгоритм дает вывод элементов, которые находятся в первом диапазоне, а не во втором. Есть ли алгоритм, который просто даст мне счет, а не разницу.

Я понимаю, что могу реализовать свою собственную версию алгоритма, описанного в ссылке, или подсчитать количество элементов после получения результата. Есть ли существующий API, который сделает это для меня эффективно.

Спасибо

1

Решение

Вы могли бы просто написать свою собственную подобную 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
}
1

Другие решения

Это такая тривиальная операция, которая не требует определенного метода. Если вы не можете позволить себе выделить временный набор для вычисления разницы, а затем получить их размер, просто рассчитайте его с помощью 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() это просто хорошо.

0

Вы можете создать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;
};
0
По вопросам рекламы [email protected]