这两种算法中的一种高效算法
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>b)
。
第二个有第一个没有的就是决定论。一个循环决定了第二个循环。所有输入都在第一个循环中读入。这意味着 CPU 可以提前准确地看到将要发生的事情,因为它拥有所有的数字,因此准确地知道 if
的每个分支将如何运行,并且可以 100% 准确地预测,加载缓存,并填满管道,让一切都提前准备好,不会错过任何一个节拍。
算法 1 无法做到这一点,因为直到循环的下一次迭代才知道下一个输入。除非输入模式是可预测的,否则它会经常猜测if(p[i-1]>p[i])
的哪个方向出错。
补充阅读:Why is it faster to process a sorted array than an unsorted array?
【讨论】:
以上是关于这两种算法中的一种高效算法的主要内容,如果未能解决你的问题,请参考以下文章