我想根据实数 vector 对整数 vector 进行排序。 例如。我有一个整数 vector (1,2,3) 和一个相应的实数 vector (0.3,0.2,0.1)。现在我想对整数进行排序,使对应于最小实数的整数排在第一位,对应于第二小实数的整数排在第二位,依此类推,即整数 vector 应该像 (3,2,1) . 代码是:
int main()
{
const unsigned int M = 5;
const unsigned int N = 10;
Eigen::MatrixXd samples = Eigen::MatrixXd::Random(M,N);
std::vector<unsigned int> indices(N);
std::iota(indices.begin(),indices.end(),0);
std::shuffle(indices.begin(),indices.end(),std::default_random_engine(1.0));
const unsigned int S = 4;
std::vector<unsigned int> A(indices.begin(),indices.begin()+S);
std::vector<unsigned int> B(indices.begin()+S,indices.end());
std::default_random_engine generator;
std::uniform_int_distribution<unsigned int> distribution(0,N-1);
const unsigned int index = distribution(generator);
std::vector<double> distances(A.size());
for(unsigned int l=0; l<A.size(); ++l)
{
distances[l] = (samples.col(index)-samples.col(A[l])).norm();
}
std::sort(A.begin(),A.end(),[&distances](unsigned int i, unsigned int j){return
distances[i]<distances[j];});
distances.resize(B.size());
for(unsigned int i=0; i<B.size(); ++i)
{
distances[i] = (samples.col(index)-samples.col(B[i])).norm();
}
std::cout << "distances:" << std::endl;
for(unsigned int i=0; i<B.size(); ++i)
{
std::cout << distances[i] << " ";
}
std::cout << std::endl;
std::cout << "indices before sorting:" << std::endl;
for(unsigned int i=0; i<B.size(); ++i)
{
std::cout << B[i] << " ";
}
std::cout << std::endl;
std::sort(B.begin(),B.end(),[&distances](unsigned int i, unsigned int j){return
distances[i]<distances[j];});
std::cout << "indices after sorting:" << std::endl;
for(unsigned int i=0; i<B.size(); ++i)
{
std::cout << B[i] << " ";
}
std::cout << std::endl;
return 0;
}
输出是:
距离:
2.42122 0.940923 1.45279 1.81009 1.96321 1.76887
排序前的索引:
2 5 4 9 8 7
排序后的索引:
7 8 9 2 5 4
为什么输出不是如下所示?
距离:
2.42122 0.940923 1.45279 1.81009 1.96321 1.76887
排序前的索引:
2 5 4 9 8 7
排序后的索引:
5 4 7 9 8 2
最佳答案
您对不同容器的不同索引感到困惑。
根据您的代码,distance[0]
不包含“索引”0的距离,但索引B[0]
的距离这是索引 2。
尝试将其与您的排序功能一起使用:
auto sort_lambda = [&samples, &index] (unsigned int l, unsigned int r) {
auto l_value = (samples.col(index)-samples.col(l)).norm();
auto r_value = (samples.col(index)-samples.col(r)).norm();
return l_value < r_value;
};
对于具有索引 vector 和值 vector 的一般情况:您可以创建对应关系图,并使用它从某个索引中获取值:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
int main()
{
using vi = std::vector<int>;
using vf = std::vector<float>;
vi indices = {2, 4, 8, 1};
vf values = {1.5, 0.5, 2.5, 4.5};
std::unordered_map<int, float> correspondences;
std::transform(begin(indices), end(indices), begin(values),
std::inserter(correspondences, end(correspondences)),
[](int i, float v) { return std::make_pair(i, v); });
std::sort(begin(indices), end(indices),
[&correspondences](int l, int r) {
return correspondences.at(l) < correspondences.at(r);
});
// Note that now using values is basically impossible because it wasn't sorted as well ... you'd need to sort it now, too!
std::copy(begin(indices), end(indices), std::ostream_iterator<int>(std::cout, ", "));
}
如果索引和/或值具有更复杂的类型,那么您可能需要使用 std::reference_wrapper
避免在构建 correspondences
时制作拷贝 map 。
当您需要经常这样做时,将值和索引分开可能没有多大意义!
更一般的,允许“待排序” vector 的重复值:
#include <algorithm>
#include <functional>
#include <iterator>
#include <vector>
template<typename A, typename B>
void sort_according_to(std::vector<A> & to_sort, std::vector<B> const & ref)
{
using pair_t = std::pair<A, std::reference_wrapper<const B>>;
std::vector<pair_t> work;
work.reserve(to_sort.size());
std::transform(
std::make_move_iterator(begin(to_sort)),
std::make_move_iterator(end(to_sort)),
begin(ref),
std::back_inserter(work),
[](A&& a, B const & b) {
return std::make_pair(std::move(a), std::cref(b));
});
std::sort(
begin(work), end(work),
[](pair_t const & l, pair_t const & r) {
return l.second.get() < r.second.get();
});
std::transform(
begin(work), end(work),
begin(to_sort),
[](pair_t & p) {
return std::move(p.first);
});
}
#include <iostream>
int main()
{
std::vector<int> ints = {1, 1, 2, 2, 3};
std::vector<float> floats = {0.1, 1.1, 0.2, 2.2, -3.14};
sort_according_to(ints, floats);
std::copy(
begin(ints), end(ints),
std::ostream_iterator<int>(std::cout, ", "));
}
关于c++ - std::vector 未按 std::sort 的预期排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59503049/