CS202 Lecture notes -- Sorting with the STL

  • James S. Plank
  • Directory: ~jplank/cs202/notes/STL-Sorting
  • Lecture notes: http://web.eecs.utk.edu/~jplank/plank/classes/cs202/Notes/STL-Sorting
  • Last modification date: Wed Sep 15 13:53:33 EDT 2021

    Sorting using the STL

    This is a really small lecture. I tell you this information in case you need it with a lab or topcoder problem.

    The standard template library supports sorting of a vector. You need to include <algorithm>. Then, to sort v, just call sort(v.begin(), v.end()). Below I have two programs that are nearly identical. One of them (src/sortlines1.cpp) sorts lines of standard input. The other (src/sortints.cpp) sorts standard input when it is read in as integers.

    /* This program sorts the lines of standard input 
       using the sort() procedure from
       the STL algorithms library. */
    
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int main()
    {
      vector <string> lines;
      string s;
      size_t i;
    
      /* Read lines of standard input into the vector "lines".
         Sort the vector using the sort() procedure, 
         and print the sorted lines. */
    
      while (getline(cin, s)) lines.push_back(s);
      sort(lines.begin(), lines.end());
      for (i = 0; i < lines.size(); i++) {
        cout << lines[i] << endl;
      }
    
      return 0;
    }
    
    /* This program sorts integers read on standard 
       input, using the sort() procedure from the 
       STL algorithms library. */
    
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int main()
    {
      vector <int> numbers;
      int n;
      size_t i;
    
      /* Read integers into the vector "numbers".
         Sort the vector using the sort() procedure, 
         and print the sorted numbers. */
    
      while (cin >> n) numbers.push_back(n);
      sort(numbers.begin(), numbers.end());
      for (i = 0; i < numbers.size(); i++) {
        cout << numbers[i] << endl;
      }
    
      return 0;
    }
    

    By default, strings are sorted lexicographically and numbers numerically (duh):

    UNIX> cat files/input-names.txt
    Sydney Ingratiate
    Arianna Exonerate
    Sarah Charcoal
    Alexis Kaitlyn Inferential
    Cole Hunter Ourselves
    Joseph Dilatory
    Julian Fluvial
    Mia Leah Skied
    Oliver Celebrate
    Liam Trisyllable
    UNIX> bin/sortlines1 < files/input-names.txt
    Alexis Kaitlyn Inferential
    Arianna Exonerate
    Cole Hunter Ourselves
    Joseph Dilatory
    Julian Fluvial
    Liam Trisyllable
    Mia Leah Skied
    Oliver Celebrate
    Sarah Charcoal
    Sydney Ingratiate
    UNIX> 
    
    UNIX> cat files/input-numbers-1.txt
    87
    76
    24
    4
    34
    27
    93
    11
    58
    54
    UNIX> bin/sortints < files/input-numbers-1.txt
    4
    11
    24
    27
    34
    54
    58
    76
    87
    93
    UNIX> 
    

    You'll note that if we sort that numerical file as strings, it will put "4" between "34" and "54":

    UNIX> bin/sortlines1 < files/input-numbers-1.txt
    11
    24
    27
    34
    4
    54
    58
    76
    87
    93
    UNIX> 
    

    And remember that sortlines1.cpp reads strings, complete with their spaces, while sortints.cpp reads numbers:

    UNIX> cat files/input-numbers-2.txt
      87 76 24
    4 34 27 93
    11 58 54
    UNIX> bin/sortlines1 < files/input-numbers-2.txt
      87 76 24
    11 58 54
    4 34 27 93
    UNIX> 
    
    UNIX> bin/sortints < files/input-numbers-2.txt
    4
    11
    24
    27
    34
    54
    58
    76
    87
    93
    UNIX> 
    

    If you want to sort, but you don't want to use the default sorting mechanism, you can provide your own comparison function. It should take two parameters of the same type as the vector (preferably const and reference) and return a bool (true or false). It should return true if the first parameter is less than the second, and false otherwise. Therefore, the following program (src/sortlines2.cpp) sorts standard input by the value of the second character in each line:

    /* This program uses a comparison function to sort a vector of strings by the
       strings' second letters, rather than the entire strings. */
    
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <string>
    using namespace std;
    
    /* Your comparison function takes as arguments, two const references to 
       the type that is in the vector (strings). */
    
    bool string_compare(const string &s1, const string &s2)
    {
      if (s1[1] < s2[1]) return true;         /* I could have just said "return (s1[1] < s2[1]);" */
      return false;
    }
    
    int main()
    {
      vector <string> lines;
      string s;
      size_t i;
    
      /* This code is the same as before, except we pass string_compare() to the sort() procedure. */
    
      while (getline(cin, s)) lines.push_back(s);
      sort(lines.begin(), lines.end(), string_compare);
      for (i = 0; i < lines.size(); i++) cout << lines[i] << endl;
    
      return 0;
    }
    
    

    I've highlighted the second characters in blue so that you can see that they are indeed sorted:

    UNIX> bin/sortlines2 < files/input.txt
    Sarah Charcoal
    Liam Trisyllable
    Mia Leah Skied
    Oliver Celebrate
    Alexis Kaitlyn Inferential
    Joseph Dilatory
    Cole Hunter Ourselves
    Arianna Exonerate
    Julian Fluvial
    Sydney Ingratiate
    UNIX>