我有兴趣在第二行的基础上对整个2d矢量进行排序。我尝试了一些仅排序第二行的代码,但是,我想要它用于整个2d向量。
#include<iostream>
#include<vector>
#include<algorithm>
int main()
{
std::vector< std::vector<int> > vect{{3, 5, 1},
{4, 8, 6},
{7, 2, 9}};
int m = vect.size();
int n = vect[0].size();
sort(vect[1].begin(), vect[1].end());
std::cout << "After sorting :\n";
for (int i=0; i<m; i++)
{
for (int j=0; j<n ;j++)
std::cout << vect[i][j] << " ";
std::cout << std::endl;
}
return 0;
}
输出如下:
3 5 1
4 6 8
7 2 9
但我希望它是
3 1 5
4 6 8
7 9 2
答案 0 :(得分:2)
创建一个转置向量的函数,因此它应该将{{3,5,1},{4,8,6},{7,2,9}}修改为{{3,4,7}, {5,8,2},{1,6,9}}。使用您的函数转置向量,然后使用自定义比较器对向量进行排序,比较行的第二个元素。然后再次调用转置函数。
转置功能可能看起来像
std::vector< std::vector<int> > transpose(std::vector< std::vector<int> >& vect)
{
std::vector< std::vector<int> > transposed(vect[0].size(), std::vector<int>());
for (size_t i = 0; i < vect.size(); ++i)
for (size_t j = 0; j < vect[0].size(); ++j)
transposed[j].push_back(vect[i][j]);
return transposed;
}
然后整个代码将是
vect = transpose(vect);
std::sort(vect.begin(), vect.end(),
[](const std::vector<int>& lhs, const std::vector<int>& rhs)
{return lhs[1] < rhs[1];});
vect = transpose(vect);
如果矢量是正方形,则可以在适当的位置进行转置,使得解决方案比这个通用的更有效。
答案 1 :(得分:1)
问题的结构不允许我们使用内置的排序功能。因为,自定义排序只会提供“行”。而且你只能比较“行”。
但是有一些替代方法可以实现这一目标。
例如,你可以通过转置矢量矢量来做到这一点。
“转置&gt;按列排序&gt;转置”可以解决您的问题。
但我的解决方案是基于另一种动态。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
template <typename T>
vector<size_t> sort_indexes(const vector<T> &v) {
// initialize original index locations
vector<size_t> idx(v.size());
iota(idx.begin(), idx.end(), 0);
// sort indexes based on comparing values in v
sort(idx.begin(), idx.end(),
[&v](size_t i1, size_t i2) {return v[i1] < v[i2];});
return idx;
}
int main()
{
std::vector< std::vector<int> > vect{{3, 5, 1, 2},
{4, 8, 6, 1},
{7, 2, 9, 5}};
int m = vect.size();
int n = vect[0].size();
int sortByRow = 1; // starts from 0, if 1 => order by using 2nd row.
/* generate reference for our actual sort operation */
std::vector<size_t> indexSort = sort_indexes(vect[sortByRow]);
/* sort each row using our reference vector */
for (int i=0; i<m; i++)
{
int temp[n];
for (int j=0; j<n; j++)
temp[j] = vect[i][indexSort[j]];
// Copy back temp[] to vector
for (int j=0; j<n; j++)
vect[i][j] = temp[j];
}
std::cout << "After sorting :\n";
for (int i=0; i<m; i++)
{
for (int j=0; j<n ;j++)
std::cout << vect[i][j] << " ";
std::cout << std::endl;
}
return 0;
}
http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/(如果您想应用就地排序,则有一些修复方法)
答案 2 :(得分:0)
你可以std::vector
std::pair<int,int>
std::vector< std::vector<int> > vect{{ 3, 5, 1 },{ 4, 8, 6 },{ 7, 2, 9 }};
std::vector<std::pair<int, int>> row;
for (int i = 0; i < vect[1].size(); ++i){
row.push_back({vect[1][i],i});
}
sort(row.begin(), row.end());
std::vector< std::vector<int> > sorted;
std::vector<int> sortedRow;
for (int i = 0; i < vect.size(); ++i){
for (int j = 0; j < vect[i].size(); ++j){
sortedRow.push_back(vect[i][row[j].second]);
}
sorted.push_back(sortedRow);
sortedRow.clear();
}
在向量的第i个元素的第一个变量中你有第二行的第i个值,而在第二个变量你有索引i的值。
然后根据对的第一个值对该向量进行排序。这样你就可以制作一个新的2D向量,在每一行中你根据对的第二个值(即旧索引)对元素进行排序。
#include <utility>
你必须app:showAsAction="always||collapseActionView"
。
答案 3 :(得分:0)
这段代码非常脏。但是你想要的代码完全相同。
#include<iostream>
#include<vector>
#include<algorithm>
std::vector< std::vector<int> > vect = { {3, 5, 1}, {4, 8, 6}, {7, 2, 9} };
int findInVector(std::vector<int> input, int temp)
{
for(int i=0;i<input.size();i++)
{
if(input[i] == temp)
{
return i;
}
}
}
bool myfunction (int i,int j)
{
bool ret;
if(i<j)
{
int i_pos = findInVector( vect[1], i);
int j_pos = findInVector( vect[1], j);
int temp = vect[0][i_pos];
vect[0][i_pos] = vect[0][j_pos];
vect[0][j_pos] = temp;
temp = vect[2][i_pos];
vect[2][i_pos] = vect[2][j_pos];
vect[2][j_pos] = temp;
ret = true;
}
else
{
ret = false;
}
return ret;
}
int main()
{
int m = vect.size();
int n = vect[0].size();
sort(vect[1].begin(), vect[1].end(), myfunction);
std::cout << "After sorting :\n";
for (int i=0; i<m; i++)
{
for (int j=0; j<n ;j++)
std::cout << vect[i][j] << " ";
std::cout << std::endl;
}
return 0;
}