Click to See Complete Forum and Search --> : List sort, urgent, please help


Minni
March 30th, 2002, 03:22 AM
I have list which stores an instances of a class. All the data in the class is
private and has member functions to access the data.
I have to sort the list on one of the class fields. I am not supposed to write any bubble sort, heap sort or anyother kind of sort routines.
I am supposed to use the appropriate sort member functions of the container class.
Iam giving an outline of the program here

#include <iostream>
#include <string>
#include<list>
#include<fstream>
#include <algorithm>

using namespace std;

class School{

public:
School(){

}

void setname(string);
void setcity(string);
string getname();
string getcity();

private:
string schoolName;
string city;
};
void School::setname( string temp)
{
schoolName =temp;
}

string School::getname()
{return schoolName;
}
void School::setcity( string temp)
{
city =temp;
}

string School::getcity()
{return city;
}
typedef list<School>school;
school sv;

school::iterator s_it;

struct NameCompare {
bool operator()(const School& a,const School& b) {
return a.getname() << b.getname(); // based on
//names only
}
};
NameCompare nameComp;
void output(const School& record)
{
cout << record.getname()<< " " <<
record.getcity()
<< "\n";
}

int main()

{
string temp;
School mysch;

for(int count=1; count<4; count++)
{
cout<<"First name:"<<endl;
getline(cin, temp);
mysch.setname(temp);
cout<<"Last name:"<<endl;
getline(cin, temp);
mysch.setcity(temp);
sv.push_back(mysch);
}
sort(sv.begin(), sv.end(), nameComp);
for(s_it=sv.begin(); s_it!=sv.end();s_it++)
output(*s_it);

return(0);
}




Can any body help me out please,this is urgent

Paul McKenzie
March 30th, 2002, 05:27 AM
First, I'll format the code so that it's easier on the eyes:

#include <iostream>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
//...
using namespace std;
//...
class School
{
public:
School(){}

void setname(string);
void setcity(string);
//...
// Note that these functions are now declared as const!!
string getname() const;
string getcity() const;

private:
string schoolName;
string city;
};
//...
void School::setname( string temp)
{
schoolName =temp;
}
//...Note the const modifier
string School::getname() const
{
return schoolName;
}
//...void School::setcity( string temp)
{
city =temp;
}
//...Note the const modifier
string School::getcity() const
{
return city;
}
//...
struct NameCompare
{
bool operator()(const School& a,const School& b)
{
// !!! This line is an error if getname() is a non-const function
return a.getname() < b.getname(); // based on
//names only
}
};
//...
void output(const School& record)
{
// !!! This line is an error if getcity() is a non-const function
cout << record.getname()<< " " <<
record.getcity() << "\n";
}



Let's start here. You are calling nameComp and output with arguments that are "const School& record". The problem with this is that inside those functions, you are calling non-const School member functions. If you pass a const reference to an object, then the object must then do all "const" actions, i.e. nothing can be changed in the class (except for variables declared as mutable).

You are calling the functions getcity() and getname(), however they are not const functions. I made the correction in the code above.

Next, the sorting is going to be a problem with VC++ unless you have the latest service pack (at least, that is what was told me). The std::list<> container has a "sort" member function:

typedef list<School>school;
school sv;
school::iterator s_it;
NameCompare nameComp;
//...
int main()
{
string temp;
School mysch;
//...
for(int count=1; count<4; count++)
{
cout<<"First name:"<<endl;
getline(cin, temp);
mysch.setname(temp);
cout<<"Last name:"<<endl;
getline(cin, temp);
mysch.setcity(temp);
sv.push_back(mysch);
}
//...Call the list::sort function
sv.sort(nameComp);
for(s_it=sv.begin(); s_it!=sv.end();s_it++)
output(*s_it);
return(0);
}



Note that you must call sv.sort(), not std::sort. The reason for this is that the list class needs to call its own sort since the list container does not contain the correct iterator types for a std::sort.

The VC++ version of STL doesn't compile this code where you have a list::sort() with a function object. The STL in VC++ is broken, and I don't know if it has been fixed in a service pack. If you aren't using VC++, then take the code I wrote and try again on another C++ compiler-- it is supposed to compile OK (but alas, it doesn't on VC++). If you use the STL found at http://www.stlport.org instead of the one that comes with VC++, then you can compile this on VC++.

I think if you are using VC++, your teacher needs to know this if you can't get the code I wrote to compile. It is a bug in the compiler's version of STL, and shouldn't be held against you. If you need further proof, you can compile the code at http://www.comeaucomputing.com/tryitout/ and try their on-line C++ compiler. The compiler there is a much better standard compiler than VC++. Over there the code compiles flawlessly, demonstrating that the problem is VC++.

Regards,

Paul McKenzie

NMTop40
March 30th, 2002, 02:58 PM
are all versions of STL broken in sort( Pred ) ? or only the older versions?

Can you get a patch from Dinkumware?

I would derive the predicate (NameCompare) from binary_function< const School&, const School&, bool > but I'm not sure if that is compulsory.


The best things come to those who rate

Paul McKenzie
March 30th, 2002, 06:08 PM
I really haven't tried it. I know that I've tried stlport and it compiles and runs the code OK. Also, Comeau's on-line compiler says the code is fine. Maybe Dinkumware does have a patch, I don't know.

Regards,

Paul McKenzie