Сортировать std :: vector <myclass>в одну строку, используя функцию сортировки из STL - PullRequest
1 голос
/ 30 декабря 2011

Вопрос касается сортировки std::vector<myclass> с использованием функции sort из класса алгоритмов STL.
Стандартный способ: sort(v.begin(), v.end(), &myfunct)
где myfunct - это:

bool myfunct( myclass first, myclass second ) {   
    if (first.value < second.value)   
        return true;   
    else return false;   
}

Подход выше занимает более одной строки. Мне интересно, как это сделать в одну строку. Можно ли определить функцию, которая сравнивает объекты myclass внутри функции сортировки? Может быть, как-то использовать это (a < b) ? a : b. Я помню, что есть что-то подобное в C #, но я забыл, как это называется. Можно ли это сделать в C ++.

Ответы [ 4 ]

6 голосов
/ 30 декабря 2011

Во-первых, вы можете просто вернуть first.value < second.value, но это не избавляет от функции.В C ++ 2011 вы можете использовать лямбда-функцию:

   std::sort(begin, end, [](myclass const& f, myclass const& s){ return f.value < s.value; });

Без C ++ 2011, я думаю, вам понадобится объект функции, потому что нет ничего, что проецирует ваш класс на значение, которое вы на самом делехотите сравнить.

Кстати, вы определенно хотите передать все, кроме самых тривиальных объектов, ссылаясь на вашу функцию сравнения.

2 голосов
/ 30 декабря 2011

Вы можете использовать boost::lambda и boost::lambda::bind (с расширенными лямбда-заполнителями)

std::sort(vec.begin(), vec.end(),
            boost::lambda::bind(&A::a, boost::lambda::_1)
            <
            boost::lambda::bind(&A::a, boost::lambda::_2));

sort передает 2 значения в функцию сравнения, поэтому вам нужно сравнить эти 2 значения. Связывающая часть кода просто выбирает переменную a из struct A из каждой сравниваемой структуры (на которую ссылаются _1 и _2).

Пример кода:

#include <iostream>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/array.hpp>

struct A
{
    A() : a(0), b(0) {}
    int a;
    int b;
};

std::ostream & operator<<(std::ostream & os, A & a)
{ return os << a.a << ":" << a.b; }

int main()
{
    boost::array<A,5> vec;
    std::fill(vec.begin(),vec.end(),A());

    vec[0].a = 1;
    vec[1].a = 3;
    vec[2].a = 4;
    vec[3].a = 0;
    vec[4].a = 2;

    std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' ');
    std::cout << std::endl;

    std::sort(vec.begin(), vec.end(),
            boost::lambda::bind(&A::a, boost::lambda::_1)
            <
            boost::lambda::bind(&A::a, boost::lambda::_2));

    std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' ');
    std::cout << std::endl;
}

Выход:

1:0 3:0 4:0 0:0 2:0 
0:0 1:0 2:0 3:0 4:0
1 голос
/ 30 декабря 2011

почему бы не скопировать вектор в набор:

std::copy(v.begin(),v.end(),std::inserter(s,s.end()));

Теперь элементы в наборе сортируются в порядке возрастания и используют set now.

0 голосов
/ 30 декабря 2011

Один вызов строки для сортировки (): sort(my_vector_of_class_object.begin(),my_vector_of_class_object.end(),compare);

Код рабочей демонстрации " вектора сортировки объектов класса " приведен ниже:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

class my_Class
{

    public:

    my_Class(int r,int n, int s):rollno(r),name(n),status(s) { }
    int getRollno() const { return rollno;}
    int getName() const { return name;}
    int getStatus() const { return status;}

    private:

    int rollno;
    int name;
    int status;
    };

    bool compare(const my_Class& x, const my_Class& y) {
    return x.getRollno() < y.getRollno();
}

int main()
{
    vector<my_Class> my_vector_of_class_object;
    vector<my_Class>::const_iterator iter;

    my_Class s1(10,20,30);
    my_Class s2(40,50,60);
    my_Class s3(25,85,9);

    my_Class s4(1,50,2);
    my_Class s5(90,70,90);
    my_Class s6(85,85,3);

    my_Class s7(20,6,89);
    my_Class s8(70,54,22);
    my_Class s9(65,22,77);


    my_vector_of_class_object.push_back(s1);
    my_vector_of_class_object.push_back(s2);
    my_vector_of_class_object.push_back(s3);

    my_vector_of_class_object.push_back(s4);
    my_vector_of_class_object.push_back(s5);
    my_vector_of_class_object.push_back(s6);


    my_vector_of_class_object.push_back(s7);
    my_vector_of_class_object.push_back(s8);
    my_vector_of_class_object.push_back(s9);



    cout <<"Before vector sort \n";

    for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter)
    std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n';
    cout <<"  \n\n";

    sort(my_vector_of_class_object.begin(),my_vector_of_class_object.end(),compare);


    cout <<"After vector sort \n";

    for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter)
    std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n';

    cout <<"  \n\n";


return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...