我已成功使用文本文件中的数据填充链接列表。链接列表包含structure
,其中包含5个string
类型的字段。
我希望按某个结构字段(升序或降序)对列表进行排序。我决定重载operator<
,但我不知道如何实现它。
到目前为止,我能够按一个固定字段对列表进行排序。以下是相关代码:
#include <iostream>
#include <list> // std::list
#include <fstream> // std::ifstream, std::ofstream
#include <string> // std::string
#include <algorithm> // std::remove, std::remove_if
#include <sstream> // std::istringstream
class Lista
{
private:
struct Person
{
// data from file
std::string lastName; // other fields omitted for keeping brevity
// operator < ( needed for correctly sorting the linked list )
bool operator< ( const Person &p )const
{
return lastName > p.lastName;
}
// constructor / destructor ... omitted for keeping brevity
};
// linked list that holds all the data from files
std::list<Person> persons;
public:
// constructor / destructor ... omitted for keeping brevity
// method for sorting the list
void sortList()
{
persons.sort();
}
};
我想添加enum
个选项,因此我可以使用只有一个重载operator<
进行排序。
这样的事情:
class Lista
{
private:
struct Person
{
//================ here I could add enum of choices ============//
enum choice { FIELD1, LASTNAME, FIELD2 }; // you get the point
bool ascending; // decides if it is ascending or descending
//==============================================================//
// data from file
std::string lastName; // other fields omitted for keeping brevity
// operator < ( needed for correctly sorting the linked list )
bool operator< ( const Person &p )const
{
if ( choice == FIELD1 )
return field1 < p.field1;
if ( choice == FIELD2 )
return field2 < p.field2;
if ( choice == LASTNAME )
return lastName > p.lastName;
}
// constructor / destructor ... omitted for keeping brevity
};
// linked list that holds all the data from files
std::list<Person> persons;
public:
// constructor / destructor ... omitted for keeping brevity
// method for sorting the list
void sortList( Person::choice ch, bool ascending)
{
// here I should use the parameters to invoke proper sorting
persons.sort();
}
我尝试将operator<
更改为函数但失败了:
// this function is inside of my private struct
bool compare( const Person &p1, const Person &p2 )const
{
return p1.lastName > p2.lastName;
}
然后我用这样的方法调用它:
void sortList()
{
persons.sort( compare );
}
但是我收到以下错误:错误C2065:&#39;比较&#39; :未声明的标识符
我对如何做到这一点真的没有其他想法,你能帮助我吗?
答案 0 :(得分:2)
enum sort_choice { FIELD1, LASTNAME, FIELD2 } ; // had to put it outside to make it accessible to main()
class Lista
{
private:
struct Person
{
std::string field1;
std::string field2;
std::string lastName;
Person(const string& f1,const string& f2,const string& lname)
{
field1=f1;
field2=f2;
lastName=lname;
}
};
struct cmp_Person // A functor for comparison
{
bool cmp_ascending;
sort_choice cmp_choice;
cmp_Person(const bool& asc,const sort_choice& ch)
{
cmp_ascending=asc;
cmp_choice=ch;
}
bool operator ()(const Person &first, const Person& second) const
{
if(cmp_ascending)
{
if ( cmp_choice == sort_choice::FIELD1 )
return first.field1 < second.field1;
if ( cmp_choice == sort_choice::FIELD2 )
return first.field2 < second.field2;
if ( cmp_choice == sort_choice::LASTNAME )
return first.lastName > second.lastName;
}
else
{
if ( cmp_choice == sort_choice::FIELD1 )
return first.field1 > second.field1;
if ( cmp_choice == sort_choice::FIELD2 )
return first.field2 > second.field2;
if ( cmp_choice == sort_choice::LASTNAME )
return first.lastName > second.lastName;
}
return true;
}
};
std::list<Person> persons;
public:
void sortList( const bool& ascending, const sort_choice& ch)
{
persons.sort(cmp_Person(ascending,ch));
}
void push_to_list(const string& f1,const string& f2,const string& lname)
{
persons.push_back(Person(f1,f2,lname));
}
void display_list()
{
list<Person>::iterator it;
for(it=persons.begin(); it!=persons.end(); it++)
{
cout<<(*it).field1<<" "<<(*it).field2<<" "<<(*it).lastName<<"\n";
}
}
};
int main()
{
Lista Lobj;
Lobj.push_to_list("a","b","c");
Lobj.push_to_list("d","e","f");
Lobj.push_to_list("g","h","i");
Lobj.push_to_list("j","k","l");
Lobj.sortList(true,sort_choice::FIELD1);
Lobj.display_list();
cout<<"\n\n";
Lobj.sortList(false,sort_choice::FIELD1);
Lobj.display_list();
}
答案 1 :(得分:0)
您可以使用以下内容:
class Lista
{
public:
enum class Sort_Type{Name,LastName};
void sort(Sort_Type type,bool asc=true)
{
switch (type) {
case Sort_Type::Name:
this->list_.sort([&](const Person& p1,const Person& p2){
if(asc)
return p1.name.compare(p2.name)>=0 ;
else
return p1.name.compare(p2.name)<0;
});
break;
case Sort_Type::LastName :
this->list_.sort([&](const Person& p1,const Person& p2){
if(asc)
return p1.lastName.compare(p2.lastName)>=0 ;
else
return p1.lastName.compare(p2.lastName)<0;
});
break;
}
}
private:
struct Person
{
string name ;
string lastName;
};
std::list<Person> list_;
};
//
Lista l;
l.sort(Lista::Sort_Type::Name);