Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Accelerated C++: Exercise 3-2

Reply
Thread Tools

Accelerated C++: Exercise 3-2

 
 
Xernoth
Guest
Posts: n/a
 
      04-12-2007
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] << " ";
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

 
Reply With Quote
 
 
 
 
zeppe
Guest
Posts: n/a
 
      04-12-2007
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
 
Reply With Quote
 
 
 
 
Jonas
Guest
Posts: n/a
 
      04-12-2007

"Xernoth" <> wrote in message
news: oups.com...
> 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] << " ";
> i++;
> }


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

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

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


 
Reply With Quote
 
Xernoth
Guest
Posts: n/a
 
      04-13-2007
On Apr 12, 11:44 pm, zeppe <z...@nospam.remove.all.this.email.it>
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.

 
Reply With Quote
 
Xernoth
Guest
Posts: n/a
 
      04-13-2007
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.


 
Reply With Quote
 
Jonas
Guest
Posts: n/a
 
      04-13-2007

"Xernoth" <> wrote in message
news: ups.com...
> 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


 
Reply With Quote
 
Xernoth
Guest
Posts: n/a
 
      04-13-2007
On Apr 13, 4:23 pm, "Jonas" <spamhereple...@gmail.com> 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.


 
Reply With Quote
 
Amit Gupta
Guest
Posts: n/a
 
      04-15-2007
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.

 
Reply With Quote
 
Andrew Koenig
Guest
Posts: n/a
 
      04-15-2007
"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.


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-15-2007
On Apr 15, 7:55 am, "Andrew Koenig" <a...@acm.org> wrote:
> "zeppe" <z...@nospam.remove.all.this.email.it> 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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Accelerated C++ - exercise 0-1 arnuld C++ 10 03-18-2007 06:54 PM
Accelerated C++ exercise 8.8 utab C++ 8 04-16-2006 06:18 PM
an interesting exercise by Accelerated C++ utab C++ 3 02-16-2006 03:50 PM
Accelerated C++ exercise utab C++ 2 02-14-2006 05:19 PM
Accelerated C++: exercise 6-1 Pete C++ 14 01-03-2006 08:34 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57