在下面的C ++代码中,我试图使用sort函数根据另一个向量排序一个向量。例如,如果v1 = (1, 2, 3, 4, 5)
和v2 = (-1.1, 1.5, 0.2, 4, 3)
,则在调用我的函数relative_sort (v1,v2)
后,我们应该v1 = (1, 3, 2, 5, 4)
。我不明白为什么代码无法正常运行。
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
void print_vector (vector<double> & v)
{
for (int i = 0 ; i < v.size() ; i++)
cout << v[i] << ' ' ;
}
void relative_sort (vector<double> & v1 , vector<double> & v2) // sort v1 based on v2
{
int n = v1.size();
if ( n != v2.size())
cout << endl << "Error: The length of v1 is not the same as v2" << endl ;
else if (n<1)
cout << endl<< "Error: Empty Vectors" << endl ;
else
{
std::sort(v1.begin(), v1.end(), [&v2](int a, int b) { return v2[a] < v2[b]; } );
}
}
////////////////////////////////////////////////////////////////////////////////
int main()
{
vector <double> v2 ;
vector <double> v1 ;
vector <double> v0 ;
double a[] = {0,1,2,3,4};
v0.assign(a,a+5);
double b[] = {1,2,3,4,5};
v1.assign(b,b+5);
double c[] = {-1.1 , 1.5 , 0.2 , 4, 3};
v2.assign(c,c+5);
cout << endl << "V0: " ;
print_vector(v0) ;
cout << endl << "V1: " ;
print_vector(v1) ;
cout << endl << "V2: " ;
print_vector(v2) ;
cout << endl ;
relative_sort (v0 , v2);
cout << endl << "V0: " ;
print_vector(v0) ;
relative_sort (v1 , v2);
cout << endl << "V1: " ;
print_vector(v1) ;
return 0;
}
上述代码的输出是
V0: 0 1 2 3 4
V1: 1 2 3 4 5
V2: -1.1 1.5 0.2 4 3
V0: 0 2 1 4 3
V1: 5 2 1 4 3
v0
的输出正确,但不适用于v1
。它似乎只适用于v0
,而不适用于任何其他矢量!
答案 0 :(得分:2)
您的代码具有未定义的行为,因为v1
的所有值都不是v2
的有效索引。特别是,5
是v2
的无效索引。
这是一种完成你想要的方式:
std::vector<std::pair<double, double>>
和v1
创建的v2
。v1
。这是该功能的更新版本。
void relative_sort (vector<double> & v1 , vector<double> & v2) // sort v1 based on v2
{
size_t n = v1.size();
if ( n != v2.size())
cout << endl << "Error: The length of v1 is not the same as v2" << endl ;
else if (n<1)
cout << endl<< "Error: Empty Vectors" << endl ;
else
{
std::vector<std::pair<double, double>> v3(n);
for ( size_t i = 0; i < n; ++i )
{
v3[i] = {v1[i], v2[i]}
}
std::sort(v3.begin(), v3.end(), [](std::pair<double, double> a,
std::pair<double, double> b)
{ return a.second < b.second; } );
for ( size_t i = 0; i < n; ++i )
{
v1[i] = v3[i].first;
}
}
}
您可以使用boost::zip_iterator
来简化该任务,但我自己并没有使用它。
更新,以回应OP的评论。
如果您将v1
更改为std::vector<size_t>
类型而不是std::vector<double>
并确保其中包含{0, 1, 2, 3, 4}
,那么您可以使用:
std::sort(v1.begin(), v1.end(),
[&v2](size_t a, size_t b) { return v2[a] < v2[b]; } );
对索引进行排序没有问题。
您还可以更新自己的功能,以便调整v1
的大小以匹配v2
的大小,并确保在调用sort
之前正确设置索引。
// Get sorted indices in v1 based on values in v2
void relative_sort (vector<size_t> & v1 , vector<double> & v2)
{
size_t n = v2.size();
if (n<1)
cout << endl<< "Error: Empty Vectors" << endl ;
else
{
v1.resize(n);
for ( size_t i = 0; i < n; ++i )
{
v1[i] = i;
}
std::sort(v1.begin(), v2.end(),
[&v2](size_t a, size_t b) { return v2[a] < v2[b]; } );
}
}