【发布时间】:2012-10-10 02:59:57
【问题描述】:
我试图使用 STL sort() 函数按存储在地图中的值对对象向量进行排序。令我大吃一惊的是,我的算法是在二次时间中运行的。我尽可能地简化了它,试图找出一个明显的错误,但无济于事。这是简化版:
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
struct a{
map<a*,float> vals;
bool operator()(a* a1, a* a2){return (vals[a1]>vals[a2]);}
void asort();
};
void a::asort(){
vector<a*> v;
map<a*,float>::iterator it = vals.begin();
for(;it!=vals.end();it++){v.push_back((*it).first);}
sort(v.begin(),v.end(),*this);
}
int main(){
a a0;
int imax=8000;
for(int i=0;i<imax;i++){a0.vals[new a]=rand();}
a0.asort();
}
当我运行 imax=2000、4000、8000 时,分别需要大约 1s、4s、18s。这怎么可能?为什么我没有得到预期的 imax*log(imax) 依赖?我对C ++的经验有限,请帮助!谢谢!
更新:感谢 Xeo、Rick 和所有回复的人。正如 Xeo 和 Rick 解释的那样,问题在于比较器(在我的情况下是 struct a 与包含值的映射)在每次比较时都会被复制,因此计算复杂度 O(imax^2 log(imax))。我可以看到的一种解决方法(因此对我的代码所做的更改很少)是使用指向映射的指针,即map<a*,float>* vals,而不是map<a*,float> vals。然后就避免了地图复制,复杂度又回到O(imax log(imax))。非常感谢!
【问题讨论】:
-
你确定时间是被排序而不是其他计算消耗的吗?
-
你真的需要在地图上调用排序吗(已经排序)
-
@FamZheng:没有其他计算,时间是你看到的代码
-
@Rick:代码不是对地图进行排序,而是基于这些指针映射到的浮点数的指针向量。
-
@Rick:我需要按地图的值排序。它是如何排序的?我不明白。你的意思是我可以在不使用 sort() 的情况下拥有我的向量 v?