C++/STL Algorithms Sorting/custom comparer

Материал из C\C++ эксперт
Перейти к: навигация, поиск

Sort objects stored in deque

<source lang="cpp">

/* The following code example is taken from the book

* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
  1. include <iostream>
  2. include <string>
  3. include <deque>
  4. include <set>
  5. include <algorithm>

using namespace std;

/* class Person

*/

class Person {

 private:
   string fn;    // first name
   string ln;    // last name
 public:
   Person() {
   }
   Person(const string& f, const string& n)
    : fn(f), ln(n) {
   }
   string firstname() const;
   string lastname() const;
   // ...

}; inline string Person::firstname() const {

   return fn;

} inline string Person::lastname() const {

   return ln;

} ostream& operator<< (ostream& s, const Person& p) {

   s << "[" << p.firstname() << " " << p.lastname() << "]";
   return s;

}

/* binary function predicate:

* - returns whether a person is less than another person
*/

bool personSortCriterion (const Person& p1, const Person& p2) {

   /* a person is less than another person
    * - if the last name is less
    * - if the last name is equal and the first name is less
    */
   return p1.lastname()<p2.lastname() ||
          (p1.lastname()==p2.lastname() &&
           p1.firstname()<p2.firstname());

} int main() {

   // create some persons
   Person p1("nicolai","josuttis");
   Person p2("ulli","josuttis");
   Person p3("anica","josuttis");
   Person p4("lucas","josuttis");
   Person p5("lucas","otto");
   Person p6("lucas","arm");
   Person p7("anica","holle");
   
   // insert person into collection coll
   deque<Person> coll;
   coll.push_back(p1);
   coll.push_back(p2);
   coll.push_back(p3);
   coll.push_back(p4);
   coll.push_back(p5);
   coll.push_back(p6);
   coll.push_back(p7);
   // print elements
   cout << "deque before sort():" << endl;
   deque<Person>::iterator pos;
   for (pos = coll.begin(); pos != coll.end(); ++pos) {
       cout << *pos << endl;
   }
   // sort elements
   sort(coll.begin(),coll.end(),    // range
        personSortCriterion);       // sort criterion
   // print elements
   cout << "deque after sort():" << endl;
   for (pos = coll.begin(); pos != coll.end(); ++pos) {
       cout << *pos << endl;
   }

} /* deque before sort(): [nicolai josuttis] [ulli josuttis] [anica josuttis] [lucas josuttis] [lucas otto] [lucas arm] [anica holle] deque after sort(): [lucas arm] [anica holle] [anica josuttis] [lucas josuttis] [nicolai josuttis] [ulli josuttis] [lucas otto]

*/        
 </source>


Use sorting criterion in sort function

<source lang="cpp">

/* The following code example is taken from the book

* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
  1. include <iostream>
  2. include <vector>
  3. include <deque>
  4. include <list>
  5. include <set>
  6. include <map>
  7. include <string>
  8. include <algorithm>
  9. include <iterator>
  10. include <functional>
  11. include <numeric>

/* PRINT_ELEMENTS()

* - prints optional C-string optcstr followed by
* - all elements of the collection coll
* - separated by spaces
*/

template <class T> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") {

   typename T::const_iterator pos;
   std::cout << optcstr;
   for (pos=coll.begin(); pos!=coll.end(); ++pos) {
       std::cout << *pos << " ";
   }
   std::cout << std::endl;

} /* INSERT_ELEMENTS (collection, first, last)

* - fill values from first to last into the collection
* - NOTE: NO half-open range
*/

template <class T> inline void INSERT_ELEMENTS (T& coll, int first, int last) {

   for (int i=first; i<=last; ++i) {
       coll.insert(coll.end(),i);
   }

} using namespace std; void printCollection (const list<int>& l) {

   PRINT_ELEMENTS(l);

} bool lessForCollection (const list<int>& l1, const list<int>& l2) {

   return lexicographical_compare
               (l1.begin(), l1.end(),   // first range
                l2.begin(), l2.end());  // second range

} int main() {

   list<int> c1, c2, c3, c4;
   // fill all collections with the same starting values
   INSERT_ELEMENTS(c1,1,5);
   c4 = c3 = c2 = c1;
   // and now some differences
   c1.push_back(7);
   c3.push_back(2);
   c3.push_back(0);
   c4.push_back(2);
   // create collection of collections
   vector<list<int> > cc;
   cc.push_back(c1);
   cc.push_back(c2);
   cc.push_back(c3);
   cc.push_back(c4);
   cc.push_back(c3);
   cc.push_back(c1);
   cc.push_back(c4);
   cc.push_back(c2);
   // print all collections
   for_each (cc.begin(), cc.end(),
             printCollection);
   cout << endl;
   // sort collection lexicographically
   sort (cc.begin(), cc.end(),    // range
         lessForCollection);      // sorting criterion
   // print all collections again
   for_each (cc.begin(), cc.end(),
             printCollection);

} /* 1 2 3 4 5 7 1 2 3 4 5 1 2 3 4 5 2 0 1 2 3 4 5 2 1 2 3 4 5 2 0 1 2 3 4 5 7 1 2 3 4 5 2 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 2 1 2 3 4 5 2 1 2 3 4 5 2 0 1 2 3 4 5 2 0 1 2 3 4 5 7 1 2 3 4 5 7

*/
       
 </source>