HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Mean, Median and Mode of a QVector

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
qvectormodemeanandmedian

Problem

I would like some help condensing this code down to size. I am trying to utilize Qt's container classes as efficiently as possible. I do not believe this code reflects my objective.

#include 
#include 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector vect;

    vect.append(0);
    vect.append(0);
    vect.append(0);
    vect.append(0);
    vect.append(1);
    vect.append(1);
    vect.append(2);
    vect.append(1);

    QVectorIterator ivect(vect);

    double median = 0;
    if(vect.count() % 2 == 0){

        median =
        static_cast((vect[vect.count() / 2 - 1] + vect[vect.count() / 2])) / 2;
    }
    else{

        median = vect[vect.count() / 2];
    }

    int sum = 0;
    while(ivect.hasNext()){

        sum += ivect.next();
    }

    double mean = static_cast(sum) / vect.count();

    QSet set;

    ivect.toFront();
    while(ivect.hasNext())
    {
        set  map;

    QSetIterator iset(set);

    ivect.toFront();
    while(iset.hasNext())
    {
        int count = 0;
        while(ivect.hasNext())
        {
            if(iset.peekNext() == ivect.next())
            {
                count++;
            }
        }
        ivect.toFront();
        map.insert(iset.next(), count);
    }

    QMapIterator imap(map);

    int maxValue = 0;
    QString mode;
    while(imap.hasNext())
    {
        imap.next();
        if(imap.value() > maxValue)
        {
           maxValue = imap.value();
           mode = QString::number(imap.key());
        }
        else if(imap.value() == maxValue)
        {
            mode = "NULL";
        }
    }

    qDebug() << set;
    qDebug() << map;
    qDebug() << "Mean:" << mean;
    qDebug() << "Median:" << median;
    qDebug() << "Mode frequency:" << maxValue;
    qDebug() << "Mode:" << mode;

    return a.exec();
}

Solution

Sorted vs Unsorted

Your QVector sequence contains an unsorted sequence of values. Your median calculation has a precondition that your sequence is sorted. Consider the sequence 1, 0, 1, what is the median?

Small, Focused, and Testable Functions

Prefer writing functions that employ the single responsibility principle. Splitting out median and testing it with different sequence types would have pointed out a problem. How about calculating the mean of an empty container? Is division by zero a problem?

Standard Algorithms

Being able to understand when you should use standard algorithms and applying them is very important. Mean can be written using std::accumulate(). Median can be written in terms of std::nth_element(). Mode can be written using boost::bimap (or utilize std::unordered_map+std::multimap) and std::upper_bound() with std::transform() to return the modes of a sequence. Not all sequences are uni-modal.

Context

StackExchange Code Review Q#109994, answer score: 4

Revisions (0)

No revisions yet.