Accelerated C++: Exercise 3-2

Discussion in 'C++' started by Xernoth, Apr 12, 2007.

  1. Xernoth

    Xernoth Guest

    Hi,

    This is my first post here, so please be gentle. I've been studying c+
    + by mostly using the book Accelerated C++ by Andrew Koenig and
    Barbara E. Moo.

    So far, I've been picking things up all right, and I've come to an
    exercise 3-2 that requires the following:
    3-2. Write a program to compute and print the quartiles (that is, the
    quarter of the numbers with the largest values, the next highest
    quarter, and so on) of a set of integers.

    After researching what quartiles are, and using the method defined
    here: http://www.statcan.ca/english/edu/power/ch12/range.htm (as from
    what I've read, there are different methods used for computing lower
    and upper quartiles) I've been able to write a console program that
    seems to calculate correctly. However, I would like advice, from a
    programming perspective, on what I could improve.

    For those who haven't read the above book, it has a unique way of
    introducing C++, as the first chapter jumps straight into the use of
    strings, so a lot of basics, like use of functions and so on, have not
    been covered as yet.

    My code is as below:

    #include <algorithm>
    #include <iostream>
    #include <vector>

    int main()
    {
    std::cout << "Enter a range of integers followed by 'end': ";

    std::vector<double> integerSet;

    int x;
    while (std::cin >> x)
    integerSet.push_back(x);

    sort(integerSet.begin(), integerSet.end());

    typedef std::vector<double>::size_type vector_Size;

    vector_Size size = integerSet.size();
    vector_Size mid = size / 2;
    double median;
    double lowerQuartile;
    double upperQuartile;

    median = size % 2 == 0 ? (integerSet[mid] + integerSet[mid-1]) / 2
    : integerSet[mid];

    vector_Size midlq = mid / 2;
    lowerQuartile = mid % 2 == 0 ? (integerSet[midlq] +
    integerSet[midlq - 1]) / 2
    : integerSet[midlq];

    vector_Size miduq = size - midlq;
    upperQuartile = mid % 2 == 0 ? (integerSet[miduq] +
    integerSet[miduq - 1]) / 2
    : integerSet[miduq - 1];

    int unsigned i = 0;
    std::cout << "Ordered Data: ";
    while (i != size)
    {
    std::cout << integerSet << " ";
    i++;
    }
    std::cout << std::endl;
    std::cout << "Median: " << median << std::endl;
    std::cout << "Lower Quartile: " << lowerQuartile << std::endl;
    std::cout << "Upper Quartile: " << upperQuartile << std::endl;

    return 0;
    }

    Thanks
     
    Xernoth, Apr 12, 2007
    #1
    1. Advertising

  2. Xernoth

    zeppe Guest

    Xernoth wrote:

    > For those who haven't read the above book, it has a unique way of
    > introducing C++, as the first chapter jumps straight into the use of
    > strings, so a lot of basics, like use of functions and so on, have not
    > been covered as yet.


    The program seems well written! Just a note: it's useless to typedef the
    std::vector<double>::size_type: use directly std::size_t.

    And, of course you'll have noticed, your program performs three times
    the same action, as the quartiles can be viewed as the medians for the
    upper and lower half of the distribution. Once you'll start studying the
    function, it would be interesting for you to try implementing a
    function that do this job and calling it three times.

    Regards,

    Zeppe
     
    zeppe, Apr 12, 2007
    #2
    1. Advertising

  3. Xernoth

    Jonas Guest

    "Xernoth" <> wrote in message
    news:...
    > Hi,
    >
    > This is my first post here, so please be gentle. I've been studying c+
    > + by mostly using the book Accelerated C++ by Andrew Koenig and
    > Barbara E. Moo.
    >
    > So far, I've been picking things up all right, and I've come to an
    > exercise 3-2 that requires the following:
    > 3-2. Write a program to compute and print the quartiles (that is, the
    > quarter of the numbers with the largest values, the next highest
    > quarter, and so on) of a set of integers.
    >
    > After researching what quartiles are, and using the method defined
    > here: http://www.statcan.ca/english/edu/power/ch12/range.htm (as from
    > what I've read, there are different methods used for computing lower
    > and upper quartiles) I've been able to write a console program that
    > seems to calculate correctly. However, I would like advice, from a
    > programming perspective, on what I could improve.
    >
    > For those who haven't read the above book, it has a unique way of
    > introducing C++, as the first chapter jumps straight into the use of
    > strings, so a lot of basics, like use of functions and so on, have not
    > been covered as yet.
    >
    > My code is as below:
    >
    > #include <algorithm>
    > #include <iostream>
    > #include <vector>
    >
    > int main()
    > {
    > std::cout << "Enter a range of integers followed by 'end': ";
    >
    > std::vector<double> integerSet;


    A vector of double called integerSet...? Better

    std::vector<int> integerSet;



    >
    > int x;
    > while (std::cin >> x)
    > integerSet.push_back(x);
    >
    > sort(integerSet.begin(), integerSet.end());
    >
    > typedef std::vector<double>::size_type vector_Size;


    Use std::size_t instead.


    >
    > vector_Size size = integerSet.size();
    > vector_Size mid = size / 2;
    > double median;
    > double lowerQuartile;
    > double upperQuartile;
    >
    > median = size % 2 == 0 ? (integerSet[mid] + integerSet[mid-1]) / 2
    > : integerSet[mid];


    If you changed the declaration of integerSet to vector<int> above, you need
    to divide by 2.0 instead of 2 to get floating point division:

    median = size % 2 == 0 ? (integerSet[mid] + integerSet[mid-1]) / 2.0 :
    integerSet[mid];

    The same applies below.

    >
    > vector_Size midlq = mid / 2;
    > lowerQuartile = mid % 2 == 0 ? (integerSet[midlq] +
    > integerSet[midlq - 1]) / 2
    > : integerSet[midlq];
    >
    > vector_Size miduq = size - midlq;
    > upperQuartile = mid % 2 == 0 ? (integerSet[miduq] +
    > integerSet[miduq - 1]) / 2
    > : integerSet[miduq - 1];
    >
    > int unsigned i = 0;
    > std::cout << "Ordered Data: ";
    > while (i != size)
    > {
    > std::cout << integerSet << " ";
    > i++;
    > }


    While the above loop works, a more idiomatic way would be

    for (std::size_t i = 0; i < size; i++) {
    std::cout << integerSet << " ";
    }

    Or, using an iterator:

    for (std::vector<int>::iterator iter = integerSet.begin(); iter !=
    integerSet.end(); iter++) {
    std::cout << *iter << " ";
    }


    > std::cout << std::endl;
    > std::cout << "Median: " << median << std::endl;
    > std::cout << "Lower Quartile: " << lowerQuartile << std::endl;
    > std::cout << "Upper Quartile: " << upperQuartile << std::endl;
    >
    > return 0;
    > }



    Apart from that, looking good :)

    --
    Jonas
     
    Jonas, Apr 13, 2007
    #3
  4. Xernoth

    Xernoth Guest

    On Apr 12, 11:44 pm, zeppe <>
    wrote:
    > The program seems well written! Just a note: it's useless to typedef the
    > std::vector<double>::size_type: use directly std::size_t.


    Thanks for that, I'm not very familiar with the uses of std::size_t,
    but I'll review and see how it can be implemented in the current
    code.
     
    Xernoth, Apr 13, 2007
    #4
  5. Xernoth

    Xernoth Guest

    Jonas wrote:
    > A vector of double called integerSet...? Better
    >
    > std::vector<int> integerSet;


    I thought about this, and I believe initially I had it set to <int>,
    but for some reason changed it to double at one point because
    something wasn't calculating correctly; though I doubt that would of
    been the cause of an incorrect calculation.
    I've not been great with naming conventions for variables, so I can
    see that integerSet can be misleading if set to <double>.

    Thanks to both for your comments and suggestions.
     
    Xernoth, Apr 13, 2007
    #5
  6. Xernoth

    Jonas Guest

    "Xernoth" <> wrote in message
    news:...
    > Jonas wrote:
    >> A vector of double called integerSet...? Better
    >>
    >> std::vector<int> integerSet;

    >
    > I thought about this, and I believe initially I had it set to <int>,
    > but for some reason changed it to double at one point because
    > something wasn't calculating correctly; though I doubt that would of
    > been the cause of an incorrect calculation.


    It was probably not incorrect, just the result of an unexpected integer
    division. Example: After the execution of

    double result = 5 / 2;

    the variable "result" holds the value 2.0, not 2.5 as one might think. This
    is because you perform an integer division, which yields an integeger that
    is then converted to a double. In your code, you divide an element from
    integerSet with 2, which is an integer division. If one of the operands is a
    floating point type, then the operation becomes a floating point operation.
    So

    double result = 5 / 2.0;

    yields the result 2.5.

    --
    Jonas
     
    Jonas, Apr 13, 2007
    #6
  7. Xernoth

    Xernoth Guest

    On Apr 13, 4:23 pm, "Jonas" <> wrote:
    > If one of the operands is a
    > floating point type, then the operation becomes a floating point operation.
    > So
    >
    > double result = 5 / 2.0;
    >
    > yields the result 2.5.


    Ah, thanks for clarifying that. I only had a quick read in regard to
    floating point arithmetic. I'll need to review that more in-depth, as
    that could be causing inaccuracies with future calculations.
     
    Xernoth, Apr 13, 2007
    #7
  8. Xernoth

    Amit Gupta Guest

    My 2 cents..

    Throw your book into some trash-can and never look back.

    You first need to understand why std::size_t and the one you defined
    are same. There is nothing like reviewing it. Second, learn floating
    point arithmetic before trying a double variable.

    Better yet, please, first learn the language before you code using
    that. I think longer term, it will be very helpful.
     
    Amit Gupta, Apr 15, 2007
    #8
  9. "zeppe" <> wrote in message
    news:461eb659$...

    > The program seems well written! Just a note: it's useless to typedef the
    > std::vector<double>::size_type: use directly std::size_t.


    Useless? Why? std::vector<double>::size_type is an unsigned type that has
    room to hold the number of elements in any vector<double>. It is not
    difficult for me to imagine machine architectures in which thie type differs
    from std::size_t, and I can see no obvious reason why std::size_t would be
    preferable on such architectures.

    I think that using an object of std::vector<double>::size_type to represent
    an index of a std::vector<double> object is an example of saying what you
    mean.
     
    Andrew Koenig, Apr 15, 2007
    #9
  10. Xernoth

    James Kanze Guest

    On Apr 15, 7:55 am, "Andrew Koenig" <> wrote:
    > "zeppe" <> wrote in message


    > news:461eb659$...


    > > The program seems well written! Just a note: it's useless to typedef the
    > > std::vector<double>::size_type: use directly std::size_t.


    > Useless? Why? std::vector<double>::size_type is an unsigned type that has
    > room to hold the number of elements in any vector<double>. It is not
    > difficult for me to imagine machine architectures in which thie type differs
    > from std::size_t, and I can see no obvious reason why std::size_t would be
    > preferable on such architectures.


    The standard says that vector<>::size_type comes from the
    allocator, and that in the default allocator, it must be a
    size_t. IMHO, whether to use std::vector<double>::size_type or
    simply size_t is largely a matter of style.

    If you're using typedef's, the issue becomes a little less
    subjective: if I've something like:

    typedef std::vector< double > VectDbl ;

    then VectDbl::size_type will automatically adjust if I change
    the typedef to use a user defined allocator; size_t won't (and
    could be wrong).

    > I think that using an object of std::vector<double>::size_type to represent
    > an index of a std::vector<double> object is an example of saying what you
    > mean.


    A very verbose way:). That's why I say it is a matter of
    style. It is certainly more explicit; you're not just using
    size_t, you're using a specific type because it is the size_type
    of std::vector.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 15, 2007
    #10
  11. Xernoth

    James Kanze Guest

    On Apr 15, 7:16 am, "Amit Gupta" <> wrote:
    > My 2 cents..


    > Throw your book into some trash-can and never look back.


    The book he's using (Koenig's "Accelerated C++") is generally
    recognized as one of the best for beginners. I'm pretty sure
    that the book didn't tell him to switch to double anytime he's
    unsure of a result.

    > You first need to understand why std::size_t and the one you defined
    > are same.


    And you need to understand why in most cases, one might prefer
    what he defined. It's a question of style, but some styles are
    preferred over others.

    > There is nothing like reviewing it. Second, learn floating
    > point arithmetic before trying a double variable.


    That, of course, is very good advice. Rarely taken, but very
    good anyway.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 15, 2007
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pete
    Replies:
    14
    Views:
    923
    Roland Pibinger
    Jan 3, 2006
  2. utab

    Accelerated C++ exercise

    utab, Feb 13, 2006, in forum: C++
    Replies:
    2
    Views:
    477
    Diego Martins
    Feb 14, 2006
  3. utab
    Replies:
    3
    Views:
    391
  4. utab
    Replies:
    8
    Views:
    535
    Default User
    Apr 16, 2006
  5. arnuld
    Replies:
    10
    Views:
    753
Loading...

Share This Page