Search code examples
c++qtqstringqtcoreqlist

Finding the second maximum number from file in Qt


I am a beginner in Qt, in the below code, I found out the maximum number, but I need to find the second maximum number, too.

int max;
max = List.at(0).toInt();

for(int i=1; i<List.size(); i++)
{
    if(List.at(i).toInt()>max)
        max = List.at(i).toInt();
    if(List.at(i).toInt()<max)
        max = List.at(0).toInt();
}

qDebug()<<"max val:"<< QString::number(max);
ui->textEdit->setText(QString::number(max));

Solution

  • The easiest way is to drop your concept and just use this;

    QList<int> intList;
    foreach (const QString &myString, list)
        intList.append(myString.toInt());
    
    qSort(intList.begin(), intList.end(), qGreater<int>());
    qDebug() << "MAX:" << intList.first();
    qDebug() << "SECOND MAX:" << intList.at(1);
    

    It is a bit slower than your original concept, O(n*log(n)) average and O(n^2) worst case complexity with something like quick sort. Other sorts like merge sort and so on might be even slower.

    However, it most of the time does not matter when using Qt since the Qt containers are inherently slower than their standard library counterparts, so I will take that this is not a main issue. If it is, you may consider switching to the standard library and use your concept which I will fix below.

    Basically, you would be using qSort to sort your content in ascending order. Note that I should the first() convenience method to get the first item as opposed to your original try of at(0). It is basically the same, but more self-explanatory.

    If you need to keep the original containers as is, you can just make a copy of it.

    If you really want to stick with your original concept, I would write this:

    main.cpp

    #include <QDebug>
    #include <QStringList>
    
    int main()
    {
        QStringList List{"10", "7", "2"};
        int max, secondMax;
        secondMax = max = INT_MIN;
    
        foreach (const QString &string, List) {
            int i = string.toInt();
            if (i > max) {
                secondMax = max;
                max = i;
            } else if (i > secondMax) {
                secondMax = i;
            }
        }
    
        if (secondMax == INT_MIN)
            secondMax = max;
    
        qDebug() << "max val:" << max;
        qDebug() << "second max val:" << secondMax;
    
        return 0;
    }
    

    main.pro

    TEMPLATE = app
    TARGET = main
    QT = core
    SOURCES += main.cpp
    CONFIG += c++11
    

    Build and Run

    qmake && make && ./main
    

    Output

    max val: 10 
    second max val: 7
    

    Note that it is better to use Qt's foreach as opposed to the C style iteration as you do not need the index after all. That being said, it is untested code, but the concept is valid, so take it pseudo-code which you may need to adjust to your need.

    It is not completely your original concept either, but I think I would do it this way.