std::unique
Объявление
<tbody> </tbody>| Определено в заголовочном файле <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) |
Описание
Удаляет все элементы, кроме первого, из каждой последовательной группы эквивалентных элементов из диапазона [first, last) и возвращает позицию нового конца диапазона.
operator==.p.policy.|
|
(до C++20) |
|
|
(начиная с C++20) |
Параметры
[first, last)
|
— | два итератора задающих диапазон элементов для обработки |
| policy | — | используемая политика выполнения. Подробнее смотрите политика выполнения. |
| p | — | бинарный предикат, который возвращает true если элементы следует считать равными. Определение функции предиката должно быть эквивалентно следующему:
Определение не должно обязательно содержать |
| Требования к типам | ||
-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).
- Относительный порядок элементов, не подлежащих удалению, сохраняется.
- Исходный диапазон
[first,last)не сокращается. Возвращается новый конец диапазонаresult:
- Все итераторы в диапазоне
[result,last)остаются валидными.
- Все итераторы в диапазоне
|
(начиная с 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?
См. также
| находит первые два соседних элемента, которые равны (или удовлетворяют заданному предикату) (шаблон функции) | |
| создает копию некоторого диапазона элементов, не содержащую последовательных дубликатов (шаблон функции) |