Reputation: 984
I am trying to complete "Accelerated C++" exercise 3-2. I have tested, and the lower quartile and medians are being calculated correctly, but the upper quartile is not.
For example, assuming the input "50, 60, 70, 80, 90, 100", it will output the quartiles as 60, 75, and 80.
I have two issues I wish to address:
1) The upper quartile, in this case, should be 90. 2) How do I get my program to display the float, or double, version of my numbers? The more precise quartile for the lower one is 62.5, not 60.
/* Write a program to compute and print the quartiles(quarter of the
* numbers with the largest values) of a set of integers
* The first quartile (Q1) is defined as the middle number between the smallest number and the median of the data set.
* The second quartile (Q2) is the median of the data.
* The third quartile (Q3) is the middle value between the median and the highest value of the data set.*/
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::endl;
using std::cout;
using std::cin;
int main() {
double x = 0;
double median, lowerQt, upperQt;
median = lowerQt = upperQt = 0;
vector<double> set;
typedef vector<double>::size_type vec_sz;
cout << "Enter integers followed by EOF: ";
while(cin >> x)
set.push_back(x);
vec_sz size = set.size();
if(size == 0) {
cout << "invalid" << endl;
return 1;
}
vec_sz mid = size / 2;
vec_sz lower = mid / 2;
vec_sz upper = size - mid;
sort(set.begin(), set.end());
median = size % 2 == 0 ? (set[mid] + set[mid - 1]) / 2 : set[mid];
lowerQt = mid % 2 == 0 ? (set[lower] + set[lower - 1]) / 2 : set[lower];
upperQt = mid % 2 == 0 ? (set[upper] + set[upper - 1]) / 2 : set[upper];
cout << lowerQt << endl << median << endl << upperQt;
}
Upvotes: 0
Views: 2732
Reputation: 14614
for starters, your code is a bit messy and hard to read. If you use modern C++ compiler you don't need that silly typedef. You can use type deduction:
auto size = set.size();
Using size % 2 == 0
as a boolean is a mouthful, it's usually written as (size % 2)
It might be prudent for clarity use that expression only once
There are three methods to determine quartiles and they give different answers, your code doesn't match two of them (because every method checks for the actual count of items in data set).Code it It matches the "1-Var Stats" method that wouldn't return value you need because of bug.
Use the median to divide the ordered data set into two halves.
If there are an odd number of data points in the original ordered data set, do not include the median (the central value in the ordered list) in either half.
If there are an even number of data points in the original ordered data set, split this data set exactly in half.
The lower quartile value is the median of the lower half of the data. The upper quartile value is the median of the upper half of the data.
I think, you expect Tukey's hinges (midhinge) one?
Use the median to divide the ordered data set into two halves.
The lower quartile value is the median of the lower half of the data. The upper quartile value is the median of the upper half of the data.
IF book on statistic is too far away, there are algorithms described in wiki and on applied math stackexchange.
Studying your code behaviors: you calculate "mid" just by dividing size of array, are not in control if you take upper or lower "middle" value. Why? Theoretically in case of uneven count you always will take upper value, if rounding up, but in fact you take only the lower one, because you operate with integer values, where result of division will be truncated. For size = 11, your mid will be 5. And what happens with "upper" index?
auto upper = size - mid; //? upper = 6 That's not right
should be
auto upper = (size + mid)/2;
That would give proper answer for first method: 60 75 90
Upvotes: 2