Как использовать функцию разделения в C для контейнера, содержащего пользовательские объекты

#c #c 11 #stl

#c #c 11 #stl

Вопрос:

Я пытаюсь использовать API parititon() для разделения объекта, хранящегося в vector. Я хочу вызвать объект функции для разделения вектора на две половины. Следующий код выдает ошибку компиляции. Как это сделать в C ?

partition.cpp:15:48: ошибка: ожидаемое первичное выражение перед токеном ‘)’ auto itr = раздел (v.begin(),v.end() -1,comp);

 #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class comp{
public:
  bool operator()(const pair<int,int>amp; p1, const pair<int,int>amp; p2) {
    return p1.first < p2.first;
  }
};


main(){
  vector<pair<int,int> > v = { {1,2} , {3,4} , {5,6} ,{7,8} };
  auto itr = partition(v.begin(),v.end()-1,comp);

}
 

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

1. Во-первых, comp -> comp{} . Далее, почему ваш функтор имеет два параметра? Должен быть один.

2. Если у нас нет двух аргументов, как я буду выполнять сравнение (мне нужно по крайней мере две пары, чтобы сравнить, что меньше). Также я не знаю синтаксиса comp{}. Пожалуйста, уточните

3. Я вижу, что раздел принимает только одинарную функцию сравнения. Итак, каковы мои варианты в этом случае? как мне передать второй аргумент. Вынужден ли я использовать лямбда-функцию, и это нельзя сделать с помощью функтора?

4. Это не порядок относительно друг друга, это разделение, основанное на некотором свойстве элемента. UnaryPredicate означает один параметр. Таким образом, вы могли бы, например, разделить элементы ниже / выше медианы, но не относительно друг друга

5. @David, это раздел, а не процедура сортировки. Если вы хотите выполнить сортировку, используйте сортировку

Ответ №1:

Как насчет

 struct comp {
    int _median;
    comp(int median): _median(median) {
    }
    bool operator()(const pair<int,int>amp; p) {
        return p.first < _median;
    }
};
 

и затем

 auto i = std::partition(v.begin(), v.end(), comp{7});
 

Может потребоваться добавить по умолчанию копировать ctr, перемещать ctr, op=, dtr и другие строительные леса

Ответ №2:

std::nth_element возможно, вам будет интересно изменить свой диапазон:

 std::vector<std::pair<int, int> > v = { {1,2} , {3,4} , {5,6} ,{7,8} };

auto mid = v.begin()   std::distance(v.begin(), v.end()) / 2;
std::nth_element(v.begin(), , v.end());
 

Теперь,

каждый элемент диапазона [v.begin(), mid) меньше или равен mid.
каждый элемент диапазона (mid, v.end()) больше или равен mid.

Ответ №3:

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

Что касается того, как передать аргумент :

  • comp является классом и не может быть передан в качестве аргумента
  • comp{} является ли созданный по умолчанию экземпляр comp , который предоставляет оператор вызова