这两种算法中的一种高效算法

Posted

技术标签:

【中文标题】这两种算法中的一种高效算法【英文标题】:Efficient one algorithm of these two algorithms 【发布时间】:2019-01-19 04:14:30 【问题描述】:

这两种算法都提供相同的输出,但第一种算法所花费的时间(>.67)几乎是第二种算法(0.36)的两倍。这怎么可能?你能告诉我这两种算法的时间复杂度吗?如果都一样,为什么时间不一样?

第一种算法:

 for (int i =0 ;i<n;i++)
        cin>>p[i];
        if(i>0)
            if(p[i-1]>p[i])
                cout<<p[i]<<" ";
            
            else
                cout<<"-1"<<" ";
            
        
    

第二个算法:

for (int i =0 ;i<n;i++)
        cin>>p[i];

    
    for (int i =0 ; i<n-1;i++)
       if(p[i]>p[i+1])
                cout<<p[i]<<" ";
            
            else
                cout<<"-1"<<" ";
             
    

【问题讨论】:

第一个可能需要 infinite 的时间,因为您在循环中有输入,而第二个没有。 欢迎来到 ***。您能否通过 1. 修复代码来改进您的问题。 2. 提供测试数据、测量时间的方式以及使其成为minimal reproducible example 所需的任何其他内容 这两种算法做不同的事情,它们花费的时间也不同。还有什么可能? 优化代码的第一级:在循环版本的每次迭代中创建一个打印语句,然后计算它们。深思熟虑! 您可以随时转储程序集并比较两者所需的指令。 【参考方案1】:

现代处理器的时间复杂度可能是一个几乎无用的性能统计数据。

在这种情况下,我们有一个算法从 0 到 n-1--O(N)--还有一个从 0 到 n-1 两次的算法--常数消失了,所以它仍然是 O(N) .第一个算法有一个额外的if 语句,该语句恰好为假一次,一个体面的编译器将消除它。我们最终得到相同数量的输入、相同数量的输出、相同数量的数组访问(排序)和相同数量的if (a&gt;b)

第二个有第一个没有的就是决定论。一个循环决定了第二个循环。所有输入都在第一个循环中读入。这意味着 CPU 可以提前准确地看到将要发生的事情,因为它拥有所有的数字,因此准确地知道 if 的每个分支将如何运行,并且可以 100% 准确地预测,加载缓存,并填满管道,让一切都提前准备好,不会错过任何一个节拍。

算法 1 无法做到这一点,因为直到循环的下一次迭代才知道下一个输入。除非输入模式是可预测的,否则它会经常猜测if(p[i-1]&gt;p[i]) 的哪个方向出错。

补充阅读:Why is it faster to process a sorted array than an unsorted array?

【讨论】:

以上是关于这两种算法中的一种高效算法的主要内容,如果未能解决你的问题,请参考以下文章

编写高效的Java代码:常用的优化技巧

算法简介及算法分析

基于高效采样算法的时序图神经网络系统

程序的灵魂---算法

希尔排序算法

Apriori算法与FP-growth算法