C++ Examples

 
Note  (applies to all the examples):  some sections of the code shown below may be over-commented.  This is because the examples are intended to help you understand the various features of the language covered in the tutorials, and not as real-life programs.  Do not use these examples as a guide on how to write good comments  (you couldn't be more misled if you do that!)


Problem:

Prompt the user for the name and age of ten persons, and print them in the same order entered, printing name, age, and printing "(youngest)" and "(oldest)" next to the persons with lowest and highest age, respectively.
 

Solution:

The first question to answer is:  do we need to store the names and ages in vectors?  Since the persons are to be printed in the same order as they are entered, we may think that we don't need to store the values entered (i.e., we prompt the user, then print, then prompt the user again, print, and so on).  The problem with this approach is that we are also asked to identify the youngest and oldest person while printing.  But finding the oldest or youngest requires that we know the ages of all the persons.  So, by the time that we got the information for the last person, it is too late to print oldest/youngest on the corresponding line.

Thus, we decide that we should store the names and ages in two vectors (a vector of strings, and a vector of ints);  we ask the user for all the information, store it in the vectors, and when we have the information for all the persons we start doing our job.

The pseudo-code should be similar to the following:

Repeat 10 times:
{

    prompt the user

    read name (store in vector)

    read age (store in vector)

}

find position (i.e., subscript) containing the lowest age
find position (i.e., subscript) containing the highest age

Repeat 10 times:
{

    print name  followed by  " - "  followed by  age

    if (position == position of the lowest age) print "(youngest)"

    if (position == position of the highest age) print "(oldest)"

}

Done.
 

There is one important detail here:  when we find the lowest and highest ages, it is not enough to determine the values of the ages (that is, it is not enough to determine that the lowest age is, say, 15 years).  Since we must be able to identify later the youngest and oldest person, we have to determine the position in the vector corresponding to the youngest and oldest.

The code in C/C++ would be:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    const int NUM_PERSONS = 10;

    vector<string> names(NUM_PERSONS);
    vector<int> ages(NUM_PERSONS);

    for (int i = 0; i < names.size(); i++)
    {
        cout << "Enter name: ";
        getline (cin, names[i]);

        cout << "Age: ";
        cin >> ages[i];
        cin.get();         // get rid of newline left in the input buffer
                            // (otherwise the next getline would fail)
    }

        /* star assuming that element 0 is both the lowest and the highest
           (after all, it is the only element checked so far, so it is both
           the lowest and the highest).  Then, compare the rest, starting
           at element 1 */

    int pos_youngest = 0, pos_oldest = 0;

    for (int i = 1; i < ages.size(); i++)
    {
        if (ages[i] < ages[pos_youngest])
        {
            pos_youngest = i;
        }

        if (ages[i] > ages[pos_oldest])
        {
            pos_oldest = i;
        }
    }

        // Now print them

    cout << endl;
    for (int i = 0; i < names.size(); i++)
    {
        cout << names[i] << " - " << ages[i];    // no newline yet...

        if (i == pos_youngest)
        {
            cout << "  (youngest)";
        }

        if (i == pos_oldest)
        {
            cout << "  (oldest)";
        }

        cout << endl;
    }

    return 0;
}
 

Exercise for the reader:  this can be slightly optimized  (not much, just a couple of details).  Try to do better than this code, in terms of execution time.


Problem:

Prompt the user for the name and age of a group of persons.  The group's size is unknown initially, so the program must keep asking the user if they want to enter more persons.  When the user finishes, the program should print the persons in order from the youngest to the oldest  (that is, the program should sort the group of persons by age).
 

Solution:

Sorting is a non-trivial task (although once you know how to do it, it seems fairly trivial).  In the book, you can find an example of sorting using the bubble-sort algorithm.  The bubble-sort is one of the most popular and widely known sorting algorithms.  However, I will show here a different algorithm to sort (more intuitive, in my opinion, although harder to implement than the bubble-sort).

The idea is the following:  we start by finding the lowest element in the group.  Once we did that, we swap it with the first element.  Thus, we have the first step of the sorting process:  the lowest is now in the first position.  Notice that to do this, we have to determine the position of the lowest element, and not the value of the lowest element (since we need to know where it is, to be able to swap it with the first element).

Now, we simply repeat the process starting at the second position.  That is, we now find the lowest value starting at the second position, and we swap that lowest value with the second one.  This will put the second lowest in the second position.  And we keep going until we did it for all the elements.

Swaping two items requires a three steps procedure.  Swapping implies assigning each element to each other.  The problem is that once we assign one, we destroy the original value of the other.  For that reason, we need an extra, temporary variable where we store the original value of one of the elements to be swapped, before overwriting it.  Thus, swapping two integer variables a and b would be done as follows"

        // swapping int variables a and b
    int tmp = a;
    a = b;
    b = tmp;    // original value of a

With this in mind, we can now sketch the pseudo-code of our sorting algorithm:

Variables:  start (int)  --  Counts where in the group we are starting to look for the lowest
                    pos_lowest (int)  --  Stores the position of the lowest value found in the specified range

For start = 0 to (size-1)        // (do we need to go up to size??)
{

    pos_lowest = start

    For i = start+1 to size
    {

        if element i < element at pos_lowest

        {

            pos_lowest = i

        }

    }

    swap element start with element pos_lowest
    (we have to swap both the age and the name!!)

}

The actual code would look like the following:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    vector<string> names;
    vector<int> ages;

    char answer;    // whether the user wants to enter more persons
    do
    {
        string name;
        int age;

        cout << "Name: ";
        getline (cin, name);
        names.push_back (name);           // append element

        cout << "Age: ";
        cin >> age;
        cin.get();
        ages.push_back (age);             // append element

        cout << "More persons (y/n)? ";
        cin >> answer;
        cin.get();
    }
    while (answer == 'y' || answer == 'Y');
 

        // Now sort the persons by age:

    for (int start = 0; start < ages.size() - 1; start++)
    {
        int pos_lowest = start;
        for (int i = start + 1; i < ages.size(); i++)
        {
            if (ages[i] < ages[pos_lowest])
            {
                pos_lowest = i;
            }
        }

            // now swap ages[start] with ages[pos_lowest]
            // and names[start] with names[pos_lowest]

        int tmp_age = ages[start];
        ages[start] = ages[pos_lowest];
        ages[pos_lowest] = tmp_age;

        string tmp_name = names[start];
        names[start] = names[pos_lowest];
        names[pos_lowest] = tmp_name;
    }

        // Now print the sorted results:

    cout << "\n\nPersons sorted by age:\n\n";
    for (int i = 0; i < names.size(); i++)
    {
        cout << names[i] << '\t' << ages[i] << endl;
    }

    return 0;
}


Problem:

Using two-dimensional arrays (i.e., vectors of vectors), write a program that prints the results of an international diving competition.  The program will prompt the user for the group of competitors, their countries, and the marks for each jump (10 rounds) for each judge, and the degree of difficulty of each jump.  The program should compute the totals and print them in the right order (i.e., sorted in descendant order by total points), indicating the three medalists).

The score for each jump is computed as follows:  given the six scores from the six judges (from 0 to 10 points), you remove the lowest and the highest, and add the remaining scores.  The total is then multiplied by the degree of difficulty (typically from 2.5 to 3.5).  The scores of all the rounds are added for the final score of the competitor.
 

Solution:

The challenge in this exercise is to figure out how should we organize the data.  We should obviously have a one-dimensional array of strings to store the names of the athletes  (why do we need an array?  well, remember that we will need to obtain all the scores for all the athletes, and then, after we sorted them by final score, we have to print them -- so, the names must be stored, so that we can play with them after we receive all the information from the user).

The final scores should also be in a one-dimensional array -- the subscript indicates the number of the athlete (that is, the score for the athlete at position N will be the value at position N in the vector of scores)

The way the competition goes is that in each round, each athlete does their jump, and the judges give their scores, which are then entered to the program.  (Do we need an array to hold the scores from each judge?)   When the judges give their scores for a particular athlete at a particular round, the program just computes the total score for that round and just adds it to the running total for the athlete.  After the ten rounds, all the elements of the array will hold the final (total) scores.

So, here goes the code (c'mon, you don't need the pseudo-code!  :-)).

To simplify a little bit the example, I will assume that no validation is required -- that is, the program asssumes that all the scores are entered correctly (i.e., numeric between 0 and 10), the degrees of difficulty are also valid numeric values, etc.
 

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

int main()
{
    const int ROUNDS = 10;
    const int JUDGES = 6;

    vector<string> athletes;
    vector<string> countries;
    vector<double> final_scores;

        // First, enter the names and countries of the competitors

    char more_athletes;
    do
    {
        string name, country;

        cout << "Athlete's name: ";
        getline (cin, name);
        athletes.push_back (name);

        cout << "Country: ";
        getline (cin, country);
        countries.push_back (country);

        cout << "More athletes (y/n)? ";
        cin >> more_athletes;
        cin.get();
    }
    while (more_athletes == 'y' || more_athletes == 'Y');

        // The size of final_scores should be the same as
        // the number of athletes.  Use resize to adjust

    final_scores.resize (athletes.size());
        // Since these are running totals, they must be
        // initialized to zero -- but that's ok, because
        // the vector initializes all its elements to zero,
        // even when resizing, the new elements are set to 0
 

        // Now go ahead one round at a time,
        // one athlete at a time for each round

    for (int round = 0; round < ROUNDS; round++)
    {
        for (int athlete = 0; athlete < athletes.size(); athlete++)
        {
            cout << athletes[athlete] << ", round " << round+1 << ":\n";

            double difficulty;

            cout << "Degree of difficulty: ";
            cin >> difficulty;

               // Get scores from each judge

            double score, total_score = 0;
            double highest_score = -1, lowest_score = 11;
                // this trick (initializing highest to -1 and
                // lowest to 11) works only in this particular
                // case, because we know for sure that the scores
                // are between 0 and 10

            for (int judge = 0; judge < JUDGES; judge++)
            {
                cout << "Mark from judge #" << judge+1 << ": ";
                cin >> score;

                total_score += score;

                if (score > highest_score)
                {
                    highest_score = score;
                }

                if (score < lowest_score)
                {
                    lowest_score = score;
                }
            }

                // The total includes all the scores -- subtract
                // highest and lowest
            total_score -= highest_score;
            total_score -= lowest_score;

                // Now times the difficulty
            total_score *= difficulty;

                // Now grant this score to the corresponding athlete
            final_scores[athlete] += total_score;
        }
    }

        // Ok, finished -- now sort the scores and print them,
        // indicating the medal winners  (notice that the sort
        // is not ascending, as in the previous example!)

    for (int start = 0; start < final_scores.size() - 1; start++)
    {
        int pos_highest = start;
        for (int i = start + 1; i < final_scores.size(); i++)
        {
            if (final_scores[i] > final_scores[pos_highest])
            {
                pos_highest = i;
            }
        }

            // swap the scores
        int tmp_score = final_scores[start];
        final_scores[start] = final_scores[pos_highest];
        final_scores[pos_highest] = tmp_score;

            // swap the athletes names
        string tmp_name = athletes[start];
        athletes[start] = athletes[pos_highest];
        athletes[pos_highest] = tmp_name;

            // swap the countries
        string tmp_country = countries[start];
        countries[start] = countries[pos_highest];
        countries[pos_highest] = tmp_country;
    }

        // Now print the results

    cout << "FINAL RESULTS:\n\n\n" << setiosflags (ios::left)
         << setw(30) << "Athlete" << setw(15) << "Country" << "Final Score\n\n";

    for (int i = 0; i < athletes.size(); i++)
    {
        cout << setw(30) << athletes[i]
             << setw(15) << countries[i]
             << setiosflags (ios::fixed) << setprecision(3)
             << setw (10) << final_scores[i];

        if (i == 0)      cout << "   GOLD MEDAL";
        else if (i == 1) cout << "   SILVER MEDAL";
        else if (i == 2) cout << "   BRONZE MEDAL";

        cout << endl;
    }

    return 0;
}



Return to main page   Return to Tutorials