РЕДАКТИРОВАТЬ: Этот ответ был применим к предыдущей, немного неясной версии вопроса.Для ответа на текущий вопрос см. Caleth's answer.
std::unique
удаляет смежные дубликаты (фактически выталкивает их в конец заданногодиапазон, чтобы сделать их очень подходящими для последующего удаления с erase
).Это не то, что вам нужно.
Если вы хотите удалить уникальные элементы, то я бы предложил решение, основанное на подсчете вхождений отдельных элементов и их удалении тех, которые встречаются только один раз.Посмотрите на эту функцию:
template <typename T>
void remove_unique(std::vector<T>& vec) {
std::map<T, int> occurrences {};
for(const auto& element : vec) {
occurrences[element]++;
}
const auto to_remove = std::remove_if(vec.begin(), vec.end(),
[&occurrences](const auto& element) {
return occurrences[element] == 1;
}
);
vec.erase(to_remove, vec.end());
}
Это удалит все уникальные элементы из std::vector
, содержащего любой тип (если он копируемый).
Для подсчета используется std::map
вхождения каждого элемента в векторе, а затем использует std::remove_if
, который (аналогично std::unique
) подталкивает элементы, которые удовлетворяют определенным критериям, к концу диапазона, чтобы сделать их пригодными для фактического удаления. определенные критерии в этом примере являются удовлетворением предиката - лямбды, которая проверяет, встречался ли данный элемент только один раз (эта информация предоставляется нашей картой, которую мы фиксируем в лямбде).После этого мы просто удаляем эти элементы с помощью вызова erase
.
Использование:
int main() {
// two 2s and two 3s
std::vector<int> vec {1, 2, 4, 3, 0, 2, 9, 3};
remove_unique(vec);
for(const auto i : vec) {
std::cout << i << ' ';
}
}
Вывод этой программы: 2 3 2 3
.Все уникальные элементы были удалены