在C ++中想进行排序实数冗长(2^20
)矢量,显然sort()
是卓有成效的。已经使用的R I用于其产生导致排序向量置换漂亮order()
功能之前。
例:
x = {24, 55, 22, 1}
然后置换
perm = {3, 2, 0, 1}
映射原x
以按升序排序x
。
我大概可以实现一些冒泡排序这并不仅仅排序X,但执行上的矢量{0,1,2,...}
相同换位和同时输出,但我相信一定有人想过这个问题,尤其是有效率的完成它。
编辑
比以前的方法更好,而无需使用辅助载体:(source on ideone):
#include <vector>
#include <algorithm>
#include <iostream>
template<class Vals>
void sortingPermutation(const Vals& values, std::vector<int>& v){
int size = values.size();
v.clear(); v.reserve(size);
for(int i=0; i < size; ++i)
v.push_back(i);
std::sort(v.begin(), v.end(), [&values](int a, int b) -> bool {
return values[a] < values[b];
});
}
int main()
{
std::vector<double> values;
values.push_back(24);
values.push_back(55);
values.push_back(22);
values.push_back(1);
std::vector<int> permutation;
sortingPermutation(values, permutation);
typedef std::vector<int>::const_iterator I;
for (I p = permutation.begin(); p != permutation.end(); ++p)
std::cout << *p << " ";
std::cout << "\n";
}
我使用的拉姆达从的C ++ 0x,但它可以用简单的仿函数对象替换:
template<class T>
struct CmpPairs{
CmpPairs(const std::vector<T> &v): v_(v) {}
std::vector<T> v_;
bool operator()(int a, int b){ return v_[a] < v_[b]; }
};
template<class T>
CmpPairs<T> CreateCmpPairs(const std::vector<T> & v) { return CmpPairs<T>(v); }
//in sortingPermutation:
std::sort(v.begin(), v.end(), CreateCmpPairs(values));
老办法与std::map
来源:ideone
我会说,最好的办法是创建整数0..N的载体,然后进行排序与比较,你想找到的有序排列的向量的相应元素的比较功能阵列。就像是:
#include <vector>
#include <algorithm>
template<class T> class sorter {
const std::vector<T> &values;
public:
sorter(const std::vector<T> &v) : values(v) {}
bool operator()(int a, int b) { return values[a] < values[b]; }
};
template<class T> std::vector<int> order(const std::vector<T> &values)
{
std::vector<int> rv(values.size());
int idx = 0;
for (std::vector<int>::iterator i = rv.begin(); i != rv.end(); i++)
*i = idx++;
std::sort(rv.begin(), rv.end(), sorter<T>(values));
return rv;
}
这最小化分配开销,因为我们不创建我们进行排序,然后提取最终permution任何大的临时对象 - 正在返回的是排序的温度相同的向量。
可以使用std::sort
排序对所述列表{(24,0),(55,2),(22,0),(1,1)}。这是不是特别漂亮,但我通常做这样的事情:
#include <vector>
#include <algorithm>
#include <utility>
typedef std::pair<double, int> Pair;
struct CmpPair
{
bool operator()(const Pair& a, const Pair& b)
{ return a.first < b.first; }
};
void sortingPermutation(
const std::vector<double>& values,
std::vector<int>& permutation)
{
std::vector<Pair> pairs;
for (int i = 0; i < (int)values.size(); i++)
pairs.push_back(Pair(values[i], i));
std::sort(pairs.begin(), pairs.end(), CmpPair());
typedef std::vector<Pair>::const_iterator I;
for (I p = pairs.begin(); p != pairs.end(); ++p)
permutation.push_back(p->second);
}
下面是测试:
#include <iostream>
int main()
{
std::vector<double> values;
values.push_back(24);
values.push_back(55);
values.push_back(22);
values.push_back(1);
std::vector<int> permutation;
sortingPermutation(values, permutation);
typedef std::vector<int>::const_iterator I;
for (I p = permutation.begin(); p != permutation.end(); ++p)
std::cout << *p << " ";
std::cout << "\n";
}