Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Структура, вектор, сортировка, STL

281
23 января 2007 года
Fan][
279 / / 19.12.2003
Существует структура:
struct F
{
string N;
int nm;
};
и вектор vector<F>
Можно ли элементы вектора отсортировать в порядке не убывания по nm средствами STL?
И вообще - как сортируются структуры?
1
23 января 2007 года
kot_
7.3K / / 20.01.2000
[QUOTE='Fan][;168758']Существует структура:
struct F
{
string N;
int nm;
};
и вектор vector<F>
Можно ли элементы вектора отсортировать в порядке не убывания по nm средствами STL?
И вообще - как сортируются структуры?[/QUOTE]
Для того что бы сортировать структуры по нужному тебе полю, необходимо перегрузить операторы == и <. После этого ты можешь использовать стандартные функции сортировки из STL.
281
23 января 2007 года
Fan][
279 / / 19.12.2003
Цитата: kot_
Для того что бы сортировать структуры по нужному тебе полю, необходимо перегрузить операторы == и <. После этого ты можешь использовать стандартные функции сортировки из STL.



Спасибо!
А можно подробнее или с примером?

309
23 января 2007 года
el scorpio
1.1K / / 19.09.2006
Код:
TMyStruct& TMyStruct::operator = (const TMyStruct &Other)
{
// Присваивание - не константный результат!!!!!
   this->Field1 = Other.Field1; this->Field2 = Other.Field2;
   return *this;
}


bool TMyStruct::operator == (const TMyStruct &Other) const
{
// Равенство, константный метод
   return ((this->Field1 == Other.Field1) && (this->Field2 == Other.Field2));
}

inline bool TMyStruct::operator != (const TMyStruct &Other) const
{
// Неравенство, константный встроенный метод
   return ! (*this == Other);
}

bool TMyStruct::operator > (const TMyStruct &Other) const
{
// Больше, константный метод
   return (this->Field1 > Other.Field1);
}

bool TMyStruct::operator < (const TMyStruct &Other) const
{
// Меньше, константный метод
   return (this->Field1 < Other.Field1);
}

inline bool TMyStruct::operator >= (const TMyStruct &Other) const
{
// Не меньше, константный встроенный метод
   return ! (*this->Field1 < Other.Field1);
}

inline bool TMyStruct::operator <= (const TMyStruct &Other) const
{
// Не больше, константный встроенный метод
   return ! (*this < Other);
}
63
23 января 2007 года
Zorkus
2.6K / / 04.11.2006
Некоторая избыточность определять столько логических операторов, достаточно одного < (в некоторых случаях потребуется еще ==, хотя он в принципе, тоже избыточен), остальные все через него выражаются. И для мнигих хороших реализаций STL будет достаточно определить только его для того, чтобы была возможность создавать вектор и сортировать его.
320
23 января 2007 года
m_Valery
1.0K / / 08.01.2007
Должно бы хватить и одного < .

Код:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

    struct F
{
 F();
 bool operator < (const F &Other)const;
 string N;
 int nm;
};
    F::F()
    {
        cout<<"input N"<<endl;
      cin>>N;
      cout<<"input nm"<<endl;
      cin>>nm;
    }
bool F::operator < (const F &Other) const
{
    return (this->nm < Other.nm);
}
int _tmain(int argc, _TCHAR* argv[])
{
    F a;
    F b;
    vector<F> vec;
    vec.push_back(a);
    vec.push_back(b);
    sort(vec.begin(),vec.end());
    for(int i = 0;i<vec.size();++i)
        cout<<vec.N.c_str()<<' '<<vec.nm<<endl;
    return 0;
}
1.8K
23 января 2007 года
k3Eahn
365 / / 19.12.2005
Кхе-кхе... Небольшая отсебятинка (чур ногами не пинать) - вариант использования std::sort с функтором:
Код:
struct F
{
    explicit F(int i) : nm(i) {};
    int getNm() const { return nm; };

private:
    int nm;
    std::string N;
};

template <typename Result, class C>
class const_comparator_t : public std::binary_function<const C&, const C&, bool>
{
    typedef Result (C::*Fntype)(void) const;

public:
    explicit const_comparator_t(Fntype _pfn) : pfn(_pfn) {};
    bool operator()(const C& left, const C& right)
    {
        return (left.*pfn)() < (right.*pfn)();
    };

private:
    Fntype pfn;
};

template <class C, typename Result>
const_comparator_t<Result, C> compare(Result (C::*pfn)(void) const)
{
    return const_comparator_t<Result, C>(pfn);
};

//Использование
int main()
{
    std::vector<F> v;
   
    v.push_back(F(5));
    v.push_back(F(7));
    v.push_back(F(3));
    v.push_back(F(6));
    v.push_back(F(1));

    std::sort(v.begin(), v.end(), compare(&F::getNm));

}
Или вообще так:
 
Код:
bool compare(const F& left, const F& right)
{
    return left.getNm() < right.getNm();
};
И использовать так:
 
Код:
std::sort(v.begin(), v.end(), &compare);
P.S.:
Но лучше, наверное, использовать для функторов boost::bind, поскольку тогда отпадает необходимость писать дополнительные функции и операторы.
63
23 января 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: k3Eahn
Или вообще так:
 
Код:
bool compare(const F& left, const F& right)
{
    return left.getNm() < right.getNm();
};
И использовать так:
 
Код:
std::sort(v.begin(), v.end(), &compare);


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

Цитата: k3Eahn

P.S.:Но лучше, наверное, использовать для функторов boost::bind, поскольку тогда отпадает необходимость писать дополнительные функции и операторы.


Ну STL все-таки входит в любую приличную C++/IDЕ, а вот boost нет;)
А вообще, насчет простоты кода - может и так.

1.8K
24 января 2007 года
k3Eahn
365 / / 19.12.2005
Цитата: Zorkus
Да можно бинарный предикат использовать, он даст большую гибкость, на случай, если вдруг потом потребуется включить другой критерий сортировки.


Для более удобного включения критерия сортировки можно сделать что-то наподобие вот этого:

Код:
template <typename Result, class C, template <typename T> class BinaryPred>
class const_comparator_t : public std::binary_function<const C&, const C&, bool>
{
    typedef Result (C::*Fntype)(void) const;

public:
    explicit const_comparator_t(Fntype _pfn) : pfn(_pfn) {};

    bool operator()(const C& left, const C& right)
    {
        return pred((left.*pfn)(), (right.*pfn)());
    };

private:
    Fntype pfn;
    BinaryPred<Result> pred;
};

template <template <typename T> class BinaryPred, class C, typename Result>
const_comparator_t<Result, C, BinaryPred> compare(Result (C::*pfn)(void) const)
{
    return const_comparator_t<Result, C, BinaryPred>(pfn);
};

//Использование
int main()
{
    std::vector<F> v;
   
    v.push_back(F(5));
    v.push_back(F(7));
    v.push_back(F(3));
    v.push_back(F(6));
    v.push_back(F(1));
   
    //Сотрируем по возрастанию
    std::sort(v.begin(), v.end(), compare<std::less>(&F::getNm));
   
    //Сотрируем по убыванию
    std::sort(v.begin(), v.end(), compare<std::greater>(&F::getNm));
     
}
63
24 января 2007 года
Zorkus
2.6K / / 04.11.2006
Честно говоря, не понял, зачем тут определять класс компаратора, имхо, хватит обычного бин. предиката, для проверки структур.
P.S. Кстати, а почему автор юзает структуру? Почему не класс?:)
281
29 января 2007 года
Fan][
279 / / 19.12.2003
Цитата: Zorkus
Кстати, а почему автор юзает структуру? Почему не класс?:)



А что, с классом проще проделывать сортировку ту, которая мне нужна?

29K
12 июня 2007 года
_Mari_
2 / / 08.05.2007
Здравствуйте!
В поисках решения моей проблемы, наткнулась на эту тему...
Но дело в том, что у меня не вектор структур, как у автора, а вектор указателей на структуру. Не могли бы вы помочь мне примером?

Структура и вектор
 
Код:
struct st
{
CString text;
int digit;
};

typedef vector<st*> v_st;


Элементы вектора необходимо отсортировать по полю digit.
Заранее спасибо.
63
12 июня 2007 года
Zorkus
2.6K / / 04.11.2006
Код:
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>

using namespace std;

struct st
{
    st(string s , int d) {this->text = s; this->digit = d;};
    string text;
    int digit;
};

typedef vector<st*> v_st;

bool compare(const st* left, const st* right)
{
    return left->digit < right->digit;
};

int main(int argc, char* argv[])
{
    v_st v1;

    v1.push_back(new st("one" , 1));
    v1.push_back(new st("three" , 3));
    v1.push_back(new st("five" , 5));
    v1.push_back(new st("seven" , 7));
    v1.push_back(new st("two" , 2));
    sort(v1.begin() , v1.end() , &compare);

    for (int i = 0; i < v1.size(); i++)
    {
        cout << v1->text << "  " << v1->digit << endl;
    }


   
}
29K
12 июня 2007 года
_Mari_
2 / / 08.05.2007
Огромное спасибо!

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог