【问题标题】:Finding the second maximum number from file in Qt在 Qt 中从文件中查找第二个最大数
【发布时间】:2014-05-17 05:12:55
【问题描述】:

我是Qt的初学者,在下面的代码中,我找到了最大数,但我也需要找到第二个最大数。

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));

【问题讨论】:

    标签: c++ qt qstring qtcore qlist


    【解决方案1】:

    最简单的方法是放弃你的概念,直接使用它;

    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);
    

    它比你原来的概念慢一点,平均 O(n*log(n)) 和 O(n^2) 最坏情况复杂度,比如快速排序。合并排序等其他排序可能会更慢。

    但是,大多数时候使用 Qt 并不重要,因为 Qt 容器本质上比它们的标准库对应物慢,所以我认为这不是主要问题。如果是,您可以考虑切换到标准库并使用我将在下面修复的概念。

    基本上,您将使用qSort 对您的内容进行升序排序。请注意,我应该使用first() convenience method 来获取第一项,而不是您最初尝试的 at(0)。基本相同,但更不言自明。

    如果您需要保留原始容器,您可以复制它。

    如果你真的想坚持你原来的概念,我会这样写:

    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
    

    构建并运行

    qmake && make && ./main
    

    输出

    max val: 10 
    second max val: 7
    

    请注意,最好使用 Qt 的 foreach 而不是 C 样式的迭代,因为您根本不需要索引。话虽这么说,它是未经测试的代码,但这个概念是有效的,所以把它当作你可能需要根据需要调整的伪代码。

    这也不完全是你最初的概念,但我想我会这样做。

    【讨论】:

    • 升序 -> 降序说明。
    • 除非您在将max 替换为更大的值时将max 降级到secondMax,否则此(第二个示例)不会总是有效。并且仅对于两个值,一旦该问题得到解决,第二个样本远远优于第一个。除非 N 非常小,否则 2*O(N) 将击败 O(NlogN)。
    • @WhozCraig:你是什么意思?我能想到的唯一问题是带有两个最大项目的不稳定容器,但这取决于 OP 在那个极端情况下想要得到什么,因此“这个概念是有效的,所以把它当作你可能需要的伪代码根据您的需要进行调整。”。不知道你指的是不是那个。
    • 我的意思是假设您的序列是 2 5 7。完成后,您的第二个算法将产生 max = 7secondMax = 2max 的替换应将 当前 max 降级为新的 secondMax
    • And for only two values the second sample is far superior to the first once that problem is addressed. -> 这可能是也可能不是过早的优化,最肯定的是,前者在维护方面“优越得多”。事实上,如果你处理性能关键代码,你不会使用 Qt,尤其是 Qt 容器。您的问题已解决,谢谢!我的稳定问题仍然存在,但这取决于 OP 在这方面到底想要什么。
    【解决方案2】:

    试试我的代码:

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

    【讨论】:

      【解决方案3】:

      你为什么不直接从升序到降序排序,然后使用索引得到最大值和第二个最大值?

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

      【讨论】:

      • 如果您真的很喜欢排序,请查看我之前关于 qSort 的回答。恕我直言,您使它变得比必要的复杂得多。
      • 抱歉,没有看到您的答案。我只是刷新了页面。
      • 没关系,你还是可以看看Qt中已经有qSort了。 :)
      猜你喜欢
      • 2015-08-03
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      相关资源
      最近更新 更多