我想找到矢量的排序顺序,例如,不重新排序矢量。
我可以想到几种方法,我想知道我是否缺少一些内置的STL或BOOST方法来做到这一点。
我想如果功能可用,代码最终会看起来像这样:
std::vector<float> unsortedSeq;
unsortedSeq.push_back( 1.1 );
unsortedSeq.push_back( 1.0 );
unsortedSeq.push_back( 0.5 );
unsortedSeq.push_back( 1.2 );
unsortedSeq.push_back( 1.15 );
std::list<std::size_t> sortOrder;
std::sort_indices( unsortedSeq.begin(), unsortedSeq.end(), sortOrder.begin() );
BOOST_FOREACH( std::size_t index, sortOrder )
{
std::cout << index << "\n"
}
2
1
0
4
3
任何人都知道任何STL或BOOST-sims会像我所说的一样完成我的要求吗?
答案 0 :(得分:4)
你会做这样的事情:
template<typename T>
class SortOrder
{
public:
SortOrder(const std::vector<T> *_sortArray) : sortArray(_sortArray) {;}
bool operator()(int lhs, int rhs) const
{
return sortArray[lhs] < sortArray[rhs];
}
private:
const std::vector<T> *sortArray;
};
//To do the sorting:
#include <boost/range/counting_range.hpp>
auto countRange = boost::range::counting_range(0, myListOfStuff.size());
//Build a vector<int> that has one index for every value in your actual vector.
vector<int> indexList(countRange.begin(), countRange.end());
std::sort(indexList.begin(), indexList.end(), SortOrder(&myListOfStuff));
这会生成一个索引向量,然后根据实际内容的向量对它们进行排序。
答案 1 :(得分:4)
std::vector<float> v;
// filled somewhere else
std::vector<std::size_t> indices(v.size());
// iota is from <numeric>, C++0x
std::iota(indices.begin(), indices.end(), 0);
std::sort(indices.begin(), indices.end(), [&v](std::size_t left, std::size_t right)
{
return v[left] < v[right];
});
答案 2 :(得分:2)
没有;你必须自己做。
幸运的是,这很容易! (这可能就是为什么没有提供)
v
n
是您输入的大小v
std::sort
索引向量,提供对输入v
的引用,以及返回v[left] < v[right]
的自定义比较器。答案 3 :(得分:1)
另一个例子,使用boost::ref
...
#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <boost/ref.hpp>
int main()
{
int n[] = { 3, 4, 1, 7, 10 };
std::vector<int> v(n, n + 5);
// print the original sequence
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// fill another vector with references to the data in the original
std::vector<boost::reference_wrapper<int> > vp;
std::transform(v.begin(), v.end(), std::back_inserter(vp), &boost::ref<int>);
// sort the references
std::sort(vp.begin(), vp.end());
// print the filtered version.
std::copy(vp.begin(), vp.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// print the original sequence again to show it hasnt changed
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
答案 4 :(得分:0)
只需对Nicol Bolas' answer进行一些修改,就可以将任何随机访问迭代器用作输入(只要它是随机迭代器并且具有reference
类型成员)。
也可以提供比较函数(就像在std::sort
中一样,默认为std :: less)。
template<typename const_iterator>
class SortOrder
{
public:
using Compare = std::function<bool(typename const_iterator::reference, typename const_iterator::reference)>;
SortOrder(const_iterator to_sort, Compare comp = std::less<typename const_iterator::reference>()) :
to_sort_(to_sort),
comp_(comp)
{}
bool operator()(int lhs, int rhs) const
{
return comp_(*(to_sort_ + lhs), *(to_sort_ + rhs));
}
private:
const_iterator to_sort_;
Compare comp_;
};
vector<double> to_sort{1, 5, 9, 2, 6, 17, 2, 8.5};
// Create integers, one value for each to_sort element
auto count_range = boost::counting_range(size_t(0), to_sort.size());
vector<int> indices(count_range.begin(), count_range.end());
// indices = 0 1 2 3 4 5 6 7
auto it = to_sort.begin();
sort(indices.begin(), indices.end(), SortOrder<decltype(it)>(it));
// indices = 0 3 6 1 4 7 2 5
可以找到一个工作示例here。