Форум » C/C++ для начинающих (C/C++ for beginners) » Как удалить дублирующиеся элементы кроме последних дублирующихся элементов из контейнера. » Ответить

Как удалить дублирующиеся элементы кроме последних дублирующихся элементов из контейнера.

Сыроежка: Допустим есть контейнер, содержащий элементы [pre2]{ 1, 2, 3, 4, 5, 4, 3, 2, 1 }[/pre2] Нужно из этого контейнера удалить дублирующиеся элементы (не меняя порядок следования элементов) кроме последних дублирующихся элементов, то есть в итоге получить контейнер, содержащий элементы [pre2]{ 5, 4, 3, 2, 1 }[/pre2] Добавление в задание условия сохранения последних дублирующихся элементов, а не первых, на первый взгляд усложняет задание, и, порой, у программистов (не только начинающих) вызывает сложности по сравнению с условием сохранения первых дублирующихся элементов. На самом деле достаточно написать функцию/алгоритм, который удаляет дублирующиеся элементы кроме первых дублирующихся элементов, а затем просто использовать реверсивные итераторы при условии, конечно, что контейнер поддерживает реверсивные итераторы! Вот как может выглядеть соответствующий алгоритм. [pre2] template <typename ForwardIterator> ForwardIterator remove_duplicates( ForwardIterator first, ForwardIterator last ) { for ( ; first != last; ++first ) { last = std::remove( std::next( first ), last, *first ); } return last;}[/pre2] Ниже приведена демонстрационная программа с использованием контейнера std::vector<int>. Сначала в программе показано, как использовать алгоритм для удаления дублирующихся элементов кроме первых дублирующихся элементов. А затем демонстрируется, как удалить дублирующиеся элементы кроме последних дублирующихся элементов с помощью реверсивных итераторов. [pre2] #include <iostream> #include <vector> #include <iterator> #include <algorithm> template <typename ForwardIterator> ForwardIterator remove_duplicates( ForwardIterator first, ForwardIterator last ) { for ( ; first != last; ++first ) { last = std::remove( std::next( first ), last, *first ); } return last; } int main() { std::vector<int> v = { 1, 2, 3, 4, 5, 4, 3, 2, 1 }; for ( const auto &item : v ) std::cout << item << ' '; std::cout << '\n'; v.erase( remove_duplicates( std::begin( v ), std::end( v ) ), std::end( v ) ); for ( const auto &item : v ) std::cout << item << ' '; std::cout << '\n'; std::cout << '\n'; v.assign( { 1, 2, 3, 4, 5, 4, 3, 2, 1 } ); for ( const auto &item : v ) std::cout << item << ' '; std::cout << '\n'; v.erase( std::begin( v ), remove_duplicates( std::rbegin( v ), std::rend( v ) ).base() ); for ( const auto &item : v ) std::cout << item << ' '; std::cout << '\n'; }[/pre2] Вывод программы на консоль: [pre2] 1 2 3 4 5 4 3 2 1 1 2 3 4 5 1 2 3 4 5 4 3 2 1 5 4 3 2 1 [/pre2]

Ответов - 1

Сыроежка: Кстати сказать, мне удалось на заданной теме заработать несколько баллов репутации на Stackoverflow, поместив представленный здесь код в качестве ответа на вопрос на Stackoverflow. C++: Remove duplicate elements from std::vector but starting from the front? Как сказал Антон Павлович Чехов, если в начале пьесы на стене висит ружье, то (к концу пьесы) оно должно выстрелить.



полная версия страницы