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);
}
Структура, вектор, сортировка, STL
struct F
{
string N;
int nm;
};
и вектор vector<F>
Можно ли элементы вектора отсортировать в порядке не убывания по nm средствами STL?
И вообще - как сортируются структуры?
struct F
{
string N;
int nm;
};
и вектор vector<F>
Можно ли элементы вектора отсортировать в порядке не убывания по nm средствами STL?
И вообще - как сортируются структуры?[/QUOTE]
Для того что бы сортировать структуры по нужному тебе полю, необходимо перегрузить операторы == и <. После этого ты можешь использовать стандартные функции сортировки из STL.
Цитата: kot_
Для того что бы сортировать структуры по нужному тебе полю, необходимо перегрузить операторы == и <. После этого ты можешь использовать стандартные функции сортировки из STL.
Спасибо!
А можно подробнее или с примером?
Некоторая избыточность определять столько логических операторов, достаточно одного < (в некоторых случаях потребуется еще ==, хотя он в принципе, тоже избыточен), остальные все через него выражаются. И для мнигих хороших реализаций STL будет достаточно определить только его для того, чтобы была возможность создавать вектор и сортировать его.
Код:
#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;
}
#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;
}
Код:
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));
}
{
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();
};
{
return left.getNm() < right.getNm();
};
Код:
std::sort(v.begin(), v.end(), &compare);
Но лучше, наверное, использовать для функторов boost::bind, поскольку тогда отпадает необходимость писать дополнительные функции и операторы.
Цитата: k3Eahn
Или вообще так:
И использовать так:
Код:
bool compare(const F& left, const F& right)
{
return left.getNm() < right.getNm();
};
{
return left.getNm() < right.getNm();
};
Код:
std::sort(v.begin(), v.end(), &compare);
Да можно бинарный предикат использовать, он даст большую гибкость, на случай, если вдруг потом потребуется включить другой критерий сортировки.
Цитата: k3Eahn
P.S.:Но лучше, наверное, использовать для функторов boost::bind, поскольку тогда отпадает необходимость писать дополнительные функции и операторы.
Ну STL все-таки входит в любую приличную C++/IDЕ, а вот boost нет;)
А вообще, насчет простоты кода - может и так.
Цитата: 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));
}
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));
}
P.S. Кстати, а почему автор юзает структуру? Почему не класс?:)
Цитата: Zorkus
Кстати, а почему автор юзает структуру? Почему не класс?:)
А что, с классом проще проделывать сортировку ту, которая мне нужна?
В поисках решения моей проблемы, наткнулась на эту тему...
Но дело в том, что у меня не вектор структур, как у автора, а вектор указателей на структуру. Не могли бы вы помочь мне примером?
Структура и вектор
Код:
struct st
{
CString text;
int digit;
};
typedef vector<st*> v_st;
{
CString text;
int digit;
};
typedef vector<st*> v_st;
Элементы вектора необходимо отсортировать по полю digit.
Заранее спасибо.
Код:
#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;
}
}
#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;
}
}
Огромное спасибо!