2015-11-05 5 views
1

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

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

Благодаря

+0

Вы можете создать «CounterIterator». – Jarod42

ответ

0

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

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 
} 
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; 
}; 
Смежные вопросы