Thread: STL Sort Algorithm

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    5

    STL Sort Algorithm

    I want to sort my FirstName data member into alphabetical order using the STL sort algorithm and then print to screen. How would I go about doing this?

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    class Person {
    
    private:
    	string FirstName;
    	string PhoneNumber;
        
    public:
    	Person(const char *name,const char *number):
    		FirstName(name), PhoneNumber(number) { }
        void FilePerson();
    	friend ostream& operator<<(ostream& os,const Person& p);
    };
    
    void Person::FilePerson()
    {
        ofstream myfile;
        myfile.open("Person.txt" , ios::app);
        myfile << FirstName << ":" << PhoneNumber << endl;
        myfile.close();
    }
    
    ostream& operator << (ostream& os,const Person& p)
    {
    	return(os<<"First Name:"<<p.FirstName<<endl<<"Phone Number:"<<p.PhoneNumber<<endl);
    }
    
    int main(int argc,char *argv[]) 
    {
      
      char nresponse;
      char name[20];
      char pnum[20];
      int i = 0;
      vector<Person> Name;
      vector<Person>::const_iterator pos;
        
      do {
      
      cout << "***********************PERSON DATABASE PROGRAM**************************" << endl;
      cout << " Enter any of the following commands:" << endl; 
      cout << " Enter n to enter a new person into database " << endl;
      cout << " Enter p to print details to screen " << endl;
      cout << " Enter f to print details to file " << endl;
      cout << " Enter s to sort name into alphabetical order " << endl;
      cout << " Enter q to quit program\n" << endl;
    
      cin >> nresponse;
        
      
      switch (nresponse){
      case 'n':
        cout << "Enter the first name: ";
        cin >> name;
    
        cout << "Enter a phone number: ";
        cin >> pnum;
    
        Name.push_back(Person(name,pnum));
        break;
    
      case 'p':
        
    	  for(pos=Name.begin();pos!=Name.end();++pos){
    			cout << *pos << endl;
    		}
    		break;
        
      case 'f':
        
    	  for(i=0;i<Name.size();i++){
          Name[i].FilePerson();
    		}
    		break;
      //case 's':
    
    	  //sort(Name.begin(),Name.end());
    	  //for(pos=Name.begin();pos!=Name.end();++pos){
    		 // cout << *pos << endl;
    	  //}
    	  
      case 'q':
    
    		Name.clear();
    	    cout << "Exiting Person Database ... " << endl;
    		break;
    
      default:
        cout << "Invalid Input" << endl;
       
    	}
      }while (nresponse != 'q');
    
     return 0;
    }
    The commented out case 's' creates an error but i'm not even sure how to access the name member because if you use just Name.begin() what is it actually sorting, name or pnum?
    Any help would be great

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You need to specify a functor that would compare on whatever value you want. A functor is a class with overloaded operator(), in this case it must take 2 Person objects and return which belongs earlier in the list, if either. You can write a function or method and convert them to functors if that is more convenient.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Example:
    Code:
    class Person {
    
    private:
    	string FirstName;
    	string PhoneNumber;
        
    public:
    	Person(const char *name,const char *number):
    		FirstName(name), PhoneNumber(number) { }
        void FilePerson();
    	friend ostream& operator<<(ostream& os,const Person& p);
    
        bool operator() (const Person &a, const Person &b) const
        {
           return whatever_your_sort_criteria_happens_to_be;
        }
        
    };

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If the comparison is art of the Person interface it should probably be operator<. You can also create a separate struct and implement its operator() and pass it to the sort function.

    The first makes sense if it makes sense to always sort Persons that way. The second makes sense if there is more than one way to sort Persons, and this particular sort is just one of them.

  5. #5
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    It wouldn't kill Daved to put sample codes of what he is saying.... (Optional code is in green)

    Example 1:
    Code:
    struct ObjectA
    {
      std::string Name, Type;
    
      bool operator < (const ObjectA &other) const
      {
        return Name < other.Name;
      }
    
      bool operator > (const ObjectA &other) const
      {
        return Name > other.Name;
      }
    
      bool operator == (const ObjectA &other) const
      {
        return Name == other.Name;
      }
    
      bool operator != (const ObjectA &other) const
      {
        return Name != other.Name;
      }
    };
    
    // later in your code..
    std::vector<ObjectA> array;
    
    // stuff is done...
    std::sort(array.begin(), array.end());
    Or

    Example 2:
    Code:
    struct ObjectA
    {
      std::string Name, Type;
    };
    
    struct ObjectB
    {
      bool operator()(const ObjectA &a, const ObjectB &b) const
      {
        return a.Name < b.Name;
      }
    };
    
    // later in your code
    std::vector<ObjectA> array;
    
    // stuff is done
    std::sort(array.begin(), array.end(), ObjectB());

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    5
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    class Person {
    
    private:
    	string FirstName;
    	string PhoneNumber;
        
    public:
    	Person(const char *name,const char *number):
    		FirstName(name), PhoneNumber(number) { }
        void FilePerson();
    	friend ostream& operator<<(ostream& os,const Person& p);
    	bool operator() (const Person &a,const Person &b)const
    	{
    		return(a.FirstName < b.FirstName);
    	}
    };
    
    void Person::FilePerson()
    {
        ofstream myfile;
        myfile.open("Person.txt" , ios::app);
        myfile << FirstName << ":" << PhoneNumber << endl;
        myfile.close();
    }
    
    ostream& operator << (ostream& os,const Person& p)
    {
    	return(os<<"First Name:"<<p.FirstName<<endl<<"Phone Number:"<<p.PhoneNumber<<endl);
    }
    
    int main(int argc,char *argv[]) 
    {
      
      char nresponse;
      char name[20];
      char pnum[20];
      int i = 0;
      vector<Person> Name;
      vector<Person>::const_iterator pos;
        
      do {
      
      cout << "***********************PERSON DATABASE PROGRAM**************************" << endl;
      cout << " Enter any of the following commands:" << endl; 
      cout << " Enter n to enter a new person into database " << endl;
      cout << " Enter p to print details to screen " << endl;
      cout << " Enter f to print details to file " << endl;
      cout << " Enter s to sort name into alphabetical order " << endl;
      cout << " Enter q to quit program\n" << endl;
    
      cin >> nresponse;
        
      
      switch (nresponse){
      case 'n':
        cout << "Enter the first name: ";
        cin >> name;
    
        cout << "Enter a phone number: ";
        cin >> pnum;
    
        Name.push_back(Person(name,pnum));
        break;
    
      case 'p':
        
    	  for(pos=Name.begin();pos!=Name.end();++pos){
    			cout << *pos << endl;
    		}
    		break;
        
      case 'f':
        
    	  for(i=0;i<Name.size();i++){
          Name[i].FilePerson();
    		}
    		break;
      case 's':
    
    	  sort(Name.begin(),Name.end());
    	  
    	  
      case 'q':
    
    		Name.clear();
    	    cout << "Exiting Person Database ... " << endl;
    		break;
    
      default:
        cout << "Invalid Input" << endl;
       
    	}
      }while (nresponse != 'q');
    
     return 0;
    }

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    5
    Ok, ignoring that last post this is what I have so far.

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    class Person {
    
    private:
    	string FirstName;
    	string PhoneNumber;
        
    public:
    	Person(const char *name,const char *number):
    		FirstName(name), PhoneNumber(number) { }
        void FilePerson();
    	friend ostream& operator<<(ostream& os,const Person& p);
    	bool operator<(const Person& p) const
    	{
    		return (FirstName < p.FirstName);
    	}
    };
    
    void Person::FilePerson()
    {
        ofstream myfile;
        myfile.open("Person.txt" , ios::app);
        myfile << FirstName << ":" << PhoneNumber << endl;
        myfile.close();
    }
    
    ostream& operator << (ostream& os,const Person& p)
    {
    	return(os<<"First Name:"<<p.FirstName<<endl<<"Phone Number:"<<p.PhoneNumber<<endl);
    }
    
    int main(int argc,char *argv[]) 
    {
      
      char nresponse;
      char name[20];
      char pnum[20];
      int i = 0;
      vector<Person> Name;
      vector<Person>::const_iterator pos;
        
      do {
      
      cout << "***********************PERSON DATABASE PROGRAM**************************" << endl;
      cout << " Enter any of the following commands:" << endl; 
      cout << " Enter n to enter a new person into database " << endl;
      cout << " Enter p to print details to screen " << endl;
      cout << " Enter f to print details to file " << endl;
      cout << " Enter s to sort name into alphabetical order " << endl;
      cout << " Enter q to quit program\n" << endl;
    
      cin >> nresponse;
        
      
      switch (nresponse){
      case 'n':
        cout << "Enter the first name: ";
        cin >> name;
    
        cout << "Enter a phone number: ";
        cin >> pnum;
    
        Name.push_back(Person(name,pnum));
        break;
    
      case 'p':
        
    	  for(pos=Name.begin();pos!=Name.end();++pos){
    			cout << *pos << endl;
    		}
    		break;
        
      case 'f':
        
    	  for(i=0;i<Name.size();i++){
          Name[i].FilePerson();
    		}
    		break;
      case 's':
    
    	  sort(Name.begin(),Name.end());
    	  for(pos=Name.begin();pos!=Name.end();++pos){
    		  cout << *pos << endl;
    	  }
    	  
      case 'q':
    
    		Name.clear();
    	    cout << "Exiting Person Database ... " << endl;
    		break;
    
      default:
        cout << "Invalid Input" << endl;
       
    	}
      }while (nresponse != 'q');
    
     return 0;
    }
    It works, but if you sort elements first and then try and print to file it doesnt work. Only if you print to file before sorting it does it actually output anything to file.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    5
    Haha sorry guys, missed a break statement in loop.
    All appears to be working

  9. #9
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Cool beans. I am of the philosophy that if you define one comparison operator, you should probably define the others. But that is a matter of implementation.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And of course, you can let Boost.Operators do it for you.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Algorithm and sort
    By grepawksed in forum C++ Programming
    Replies: 9
    Last Post: 03-27-2006, 11:23 AM
  2. STL? sort
    By suligab in forum C++ Programming
    Replies: 4
    Last Post: 12-06-2005, 11:14 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. sort(begin,end,op) stl algorithm
    By kes103 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2003, 10:58 AM
  5. STL algorithm question
    By Reggie in forum C++ Programming
    Replies: 1
    Last Post: 04-22-2003, 09:04 AM