Reputation: 742
I'm looking for a c++ method that is able to order the rows of a matrix by a decreasing order of the values in a specific column.
For example, if this is my input:
matrix = [1,2,3;
2,4,1;
0,5,2]
the call of the method(matrix,3) should provide the following output:
outputMatrix = [1,2,3;
0,5,2;
2,4,1]
In MATLAB this can be done by the calling of the function:
outputMatrix = sortrows(matrix,3).
What about c++? (In both cases, 3 is the index of the column).
Moreover in the script I'm working, the matrix is defined as a vector of vector: std::vector<std::vector<double> > matrix
[EDIT] I add another example:
input = [4,5,6;
0,2,8;
1,2,3;
6,7,9]
outputMatrix = sortrows(input,2); Column 2, ordered, is: 9,8,6,3; so I have to order the rows and copy the elements of the first two columns (respectively 0 and 1).
outputMatrix = [6,7,9;
0,2,8;
4,5,6;
1,2,3]
I report here the method I wrote to do this, but I don't know if this is a fast way:
std::vector<std::vector<double> > sortrows(std::vector<std::vector<double> > matrix,int col){
int length = matrix[col].size();
std::vector<std::vector<double> > output(3,std::vector<double>(length*length));
output[col] = matrix[col];
std::sort(output[col].begin(),output[col].end(),std::greater<double>());
for (int i = 0; i < length*length;i++){
int index = 0;
while(output[col][i]!=matrix[col][index]){index++;}
output[0][i]=matrix[0][index];
output[1][i]=matrix[1][index];
matrix[2][index] = -1;
}
return output;
}
Upvotes: 3
Views: 9793
Reputation: 66
template<typename T>
void SortRows(std::vector<std::vector<T>>& inputVector,int col)
{
bool stay{true};
for (int ii = 0; ii< inputVector.size();ii++)
{
if(stay)
{
stay = false;
for(int jj=0;jj<inputVector.size()-1;jj++)
{
if(inputVector[jj][col] < inputVector[jj+1][col])
{
inputVector[jj].swap(inputVector[jj+1]);
stay = true;
}
}
}
else
{
break;
}
}
}
This is a bubble sort algorithm that solves your problem.
Notice that this algorithm changes the input with descending order due to '<' sign, you can use '>' for ascending order.
If you have any hesitation, please ask again.
Upvotes: 0
Reputation: 3260
Something like following (in C++11), sort the matrix rows based on a specific column
void sortrows(std::vector<std::vector<double>>& matrix, int col) {
std::sort(matrix.begin(),
matrix.end(),
[col](const std::vector<double>& lhs, const std::vector<double>& rhs) {
return lhs[col] > rhs[col];
});
}
Also notice, this code changes the original matrix rather than returning a new matrix.
non C++11 version:
class Compare {
public:
Compare(int col) : col_(col) {}
bool operator()(std::vector<double>& lhs, std::vector<double>& rhs) {
return lhs[col_] > rhs[col_];
}
private:
int col_;
};
void sortrows(std::vector<std::vector<double>>& matrix, int col) {
std::sort(matrix.begin(), matrix.end(), Compare(col));
}
Upvotes: 6