On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 13.06.19 15:42. Заголовок: Как удалить дублирующиеся элементы кроме последних дублирующихся элементов из контейнера.


Допустим есть контейнер, содержащий элементы
{ 1, 2, 3, 4, 5, 4, 3, 2, 1 }

Нужно из этого контейнера удалить дублирующиеся элементы (не меняя порядок следования элементов) кроме последних дублирующихся элементов, то есть в итоге получить контейнер, содержащий элементы
{ 5, 4, 3, 2, 1 }

Добавление в задание условия сохранения последних дублирующихся элементов, а не первых, на первый взгляд усложняет задание, и, порой, у программистов (не только начинающих) вызывает сложности по сравнению с условием сохранения первых дублирующихся элементов.

На самом деле достаточно написать функцию/алгоритм, который удаляет дублирующиеся элементы кроме первых дублирующихся элементов, а затем просто использовать реверсивные итераторы при условии, конечно, что контейнер поддерживает реверсивные итераторы!

Вот как может выглядеть соответствующий алгоритм.

 
template <typename ForwardIterator>
ForwardIterator remove_duplicates( ForwardIterator first, ForwardIterator last )
{
for ( ; first != last; ++first )
{
last = std::remove( std::next( first ), last, *first );
}

return last;}

Ниже приведена демонстрационная программа с использованием контейнера std::vector<int>.

Сначала в программе показано, как использовать алгоритм для удаления дублирующихся элементов кроме первых дублирующихся элементов. А затем демонстрируется, как удалить дублирующиеся элементы кроме последних дублирующихся элементов с помощью реверсивных итераторов.
 
#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';
}

Вывод программы на консоль:
 
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


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 1 [только новые]





ссылка на сообщение  Отправлено: 11.02.21 01:04. Заголовок: Кстати сказать, мне ..


Кстати сказать, мне удалось на заданной теме заработать несколько баллов репутации на Stackoverflow, поместив представленный здесь код в качестве ответа на вопрос на Stackoverflow.

C++: Remove duplicate elements from std::vector but starting from the front?

Как сказал Антон Павлович Чехов, если в начале пьесы на стене висит ружье, то (к концу пьесы) оно должно выстрелить.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 0
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет