Есть ли потомки std::vector, которые могут объединять и сортировать?

#c #sorting #merge #stl #stdvector

#c #сортировка #слияние #stl #stdvector

Вопрос:

Я работаю с std ::vectors для графической программы. Эти векторы содержат позиции на экране, и они сортируются. Теперь я хотел бы объединить их вместе и сохранить фактическую сортировку, удалив возможные дубликаты, что-то вроде этого:

 vector1 : [2, 6, 10]
vector2 : [1, 5, 6, 10]
result  : [1, 2, 5, 6, 10]
  

Для хорошего понимания: я уже запрограммировал себе функцию для выполнения фактического слияния на основе базовых функций std :: vector at() insert() , таких как , , size() , но моя функция, похоже, является разрывом в производительности (я полагаю, O (n 2)).

Я ищу другие классы std (std:: vector потомки, если это возможно, для простоты программирования), которые содержат merge() и sort(kind="unique") в качестве базовых методов.

Кто-нибудь знает, существуют ли такие классы в STL?

Комментарии:

1. Неправильное мышление. Алгоритмы STL являются шаблонами функций, не являющихся членами.

Ответ №1:

STL имеет эту концепцию разделения контейнеров и алгоритмов, поэтому, хотя std::vector на самом деле у него нет членов для сортировки или объединения, STL предоставляет все необходимые алгоритмы с помощью шаблонов функций, не являющихся членами, которые обрабатывают итераторы.

Например. для сортировки вектора, который вы бы назвали

 std::sort(vector1.begin(),vector1.end());
  

Проверьте заголовок алгоритма для получения дополнительной ссылки, а именно std::sort и std::merge .

Для объединения и удаления дубликатов вы можете использовать std::set_union , что, вероятно, ваш лучший выбор. Вот пример рабочего кода.

Вот руководство по итераторам, хотя для этой конкретной задачи вам понадобится только понятный vector::begin() и vector::end() .

Для удаления дубликатов из одного контейнера вы обычно используете std::unique() или std::unique_copy() , как упоминал @unwind .

Есть одно предостережение с std::unique() и другими алгоритмами «удаления», такими как std::remove() , которое вытекает из того «разделения контейнеров и алгоритмов», о котором я упоминал: алгоритм не имеет средств для фактического удаления элементов из контейнера — ему был предоставлен итератор или диапазон, но он понятия не имеет о фактическом типеи реализация контейнера.

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

Вот как это делается с std::unique() :

 vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
  

std::unique_copy этот трюк не потребуется, но он в значительной степени скопирует весь вектор, поэтому это имеет смысл, только если вы все равно намеревались его скопировать.

Комментарии:

1. Вероятно, следует также сказать что-то о требовании удаления дубликатов. std::unique() ?

2. ах да, пропустил эту часть. Забавно, как это на самом деле компилирует вещи

3. Что я действительно должен был упомянуть с самого начала, так это std::set_union . Это легко не заметить — я думаю, название немного вводит в заблуждение. Однако это решение по умолчанию для уникального слияния.

4. Привет, @Ap31, set_union() это действительно то, что я ищу, я нашел это на cplusplus.com ссылка, я протестировал его, и он работает нормально. Может быть, лучше всего отредактировать ваш первый ответ, например, окончательное решение будет в ответе, а не в следующих комментариях.

5. @Dominique Я отредактировал ответ, чтобы добавить упоминание set_union() , вы хотите, чтобы я удалил всю std::unique часть? Я все еще считаю это несколько актуальным