Пространства имён
Варианты
Действия

std::unique

Материал из cppreference.com
< cpp‎ | algorithm
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Политики исполнения (C++17)
Немодифицирующие операции над последовательностями
(C++11)(C++11)(C++11)
(C++17)
Модифицирующие операции над последовательностями
Операции разбиения
Операции сортировки
(C++11)
Операции двоичного поиска
Операции с наборами (в отсортированных диапазонах)
Операции с кучей
(C++11)
Операций минимума/максимума
(C++11)
(C++17)

Операции перестановки
Числовые операции
Операции с неинициализированной памятью
(C++17)
(C++17)
(C++17)
Библиотека C
 

Содержание

[править] Объявление

Определено в заголовочном файле <algorithm>
template< class ForwardIt >
ForwardIt unique( ForwardIt first, ForwardIt last );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt >

ForwardIt unique( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last );
(2) (начиная с C++17)
template< class ForwardIt, class BinaryPred >
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPred p );
(3) (constexpr начиная с C++20)
template< class ExecutionPolicy,

          class ForwardIt, class BinaryPred >
ForwardIt unique( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last, BinaryPred p );
(4) (начиная с C++17)

[править] Описание

Удаляет все элементы, кроме первого, из каждой последовательной группы эквивалентных элементов из диапазона [firstlast) и возвращает позицию нового конца диапазона.

1,2) Элементы сравниваются с помощью operator==.
3,4) Элементы сравниваются с использованием заданного бинарного предиката p.
2,4) Аналогично (1,3), но выполняется в соответствии с policy.
Эти перегрузки не участвуют в разрешении перегрузки, если только

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> не равно true.

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> не равно true.

(начиная с C++20)

[править] Параметры

[firstlast) два итератора задающих диапазон элементов для обработки
policy используемая политика выполнения. Подробнее смотрите политика выполнения.
p бинарный предикат, который возвращает ​true если элементы следует считать равными.

Определение функции предиката должно быть эквивалентно следующему:

 bool pred(const Type1 &a, const Type2 &b);

Определение не должно обязательно содержать const &, но функция не должна модифицировать принимаемые объекты.
Типы Type1 и Type2 должны быть таковы, что объект типа ForwardIt может быть разыменован и затем неявно преобразован в оба из них.

Требования к типам
-
ForwardIt должен соответствовать требованиям ForwardIterator.
-
The type of dereferenced ForwardIt must meet the requirements of MoveAssignable.

[править] Возвращаемое значение

ForwardIt на новый конец диапазона

[править] Предусловия

[править] Постусловия

[править] Исключения

[править] Сложность

Для непустых диапазонов ровно std::distance(first,last) - 1 применений соответствующего предиката.

[править] Заметки

Удаление производится перемещением элементов в диапазоне таким образом, чтобы элементы, не подлежащие удалению, были в начале диапазона.

  • Перемещение выполняется с помощью copy assignment (до C++11)move assignment (начиная с C++11).
  • Относительный порядок элементов, не подлежащих удалению, сохраняется.
  • Исходный диапазон [firstlast) не сокращается. Возвращается новый конец диапазона result:
  • Все итераторы в диапазоне [resultlast) остаются валидными.
  • Каждый элемент из [resultlast) имеет допустимое, но не определённое значение.
(начиная с C++11)

За вызовом unique обычно следует вызов метода erase контейнера содержащего диапазон, удаляющий элементы с неопределёнными значениями.

[править] Возможная реализация

Первый вариант
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return last;
 
    ForwardIt result = first;
    while (++first != last) {
        if (!(*result == *first)) {
            *(++result) = *first;
        }
    }
    return ++result;
}
Второй вариант
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style=""><tr><td class="mbox-empty-cell"></td><td class="mbox-text" style="">Этот раздел не завершён </td></tr></table>[[Категория:Todo without reason]]
Третий вариант
template<class ForwardIt, class BinaryPredicate>
ForwardIt unique(ForwardIt first, ForwardIt last,
                       BinaryPredicate p)
{
    if (first == last)
        return last;
 
    ForwardIt result = first;
    while (++first != last) {
        if (!p(*result, *first)) {
            *(++result) = *first;
        }
    }
    return ++result;
}
Четвёртый вариант
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style=""><tr><td class="mbox-empty-cell"></td><td class="mbox-text" style="">Этот раздел не завершён </td></tr></table>[[Категория:Todo without reason]]

[править] Пример

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cctype>
 
int main() 
{
    // удаление повторяющихся элементов (обычное использование)
    std::vector<int> v{1,2,3,1,2,3,3,4,5,4,5,6,7};
    std::sort(v.begin(), v.end()); // 1 1 2 2 3 3 3 4 4 5 5 6 7 
    auto last = std::unique(v.begin(), v.end());
    // v сейчас содержит {1 2 3 4 5 6 7 x x x x x x}, где 'x' обозначает неопределённый элемент
    v.erase(last, v.end()); 
    for (int i : v)
      std::cout << i << " ";
    std::cout << "\n";
 
    // удаление последовательных повторяющихся пробелов
    std::string s = "wanna go    to      space?";
    auto end = std::unique(s.begin(), s.end(), [](unsigned char l, unsigned char r){
        return std::isspace(l) && std::isspace(r);
    });
    // s сейчас содержит "wanna go to space?xxxxxxxx", где 'x' обозначает неопределённый символ
    std::cout << std::string(s.begin(), end) << '\n';
}

Вывод:

1 2 3 4 5 6 7
wanna go to space?

[править] См. также

находит первые два соседних элемента, которые равны (или удовлетворяют заданному предикату)
(шаблон функции) [править]
создает копию некоторого диапазона элементов, не содержащую последовательных дубликатов
(шаблон функции) [править]