-2

I was trying to sort a two vector first based on values of 1st column and then sort the 2nd column of the sorted vector based on the corresponding values of first column. That is first sort 1st column in decreasing order then sort 2nd column in increasing order where corresponding values of 1st column are same . Example if I entered a vector say:

5 8
4 6
3 1
5 2
4 9
5 3
4 7

Then the sorted output should look like:

4 6
4 7
4 9
5 2
5 3
5 8
3 1

This is what I wanted to do. I wrote this piece of code but I don't know what is going wrong. My code:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool sor_col(vector<int> &v1, vector<int> &v2){
    if(v1[0]==v2[0]){
        return v1[1]<v2[1];
    }
    return false;
}
bool sort_d(vector<int> &v1,vector<int> &v2){
    return v1[0]>v2[0];
}
int main(){
    int n,k,x,y;
    cin>>n>>k;
    vector<vector<int>> v(n);
    for(int i=0;i<n;i++){
        cin>>x>>y;
        v[i].push_back(x);
        v[i].push_back(y);
    }
    sort(v.begin(),v.end(),sort_d);
    sort(v.begin(),v.end(),sor_col);
    return 0;
}

Can anyone help me figure out what is going on?

Pirogrammer
  • 150
  • 3
  • 18
itti_da
  • 65
  • 8
  • Can [this](https://iq.opengenus.org/sort-2d-vector-in-cpp/) help you? – Pirogrammer Mar 25 '21 at 08:27
  • Please provide a [mcve], including hard-coded start values, error messages and expected output. As a new user, also take the [tour] and read [ask]. – Ulrich Eckhardt Mar 25 '21 at 08:27
  • it's not exactly the same form of data but this post can help you : https://stackoverflow.com/questions/60453780/access-to-iterator-in-lambda-function-of-an-algorithm-cause-me-segmentation-faul – Kafka Mar 25 '21 at 08:30
  • I don't really follow the sorting order... Why should `3 1` be last for example? If it wasn't for that a plain call to `std::sort(begin(v), end(v))` would be enough (at least using the input data you show, see e.g. [this compiler explorer example](https://godbolt.org/z/4Tacd6Ye8)). – Some programmer dude Mar 25 '21 at 08:46
  • @Someprogrammerdude The example does not match the description, the description says first column decreasing order, so 3 should be the last, but 5 should be the first, not 4. – mch Mar 25 '21 at 08:52
  • @Someprogrammerdude second column should be in increasing order from the description ;-) – mch Mar 25 '21 at 08:56
  • As a side-note for the OP: If you have a fixed number of elements for the nested vector, why not use `std::array` instead? As in `std::vector>`? Or perhaps even `std::pair`? As in `std::vector>`? (Or alternatively `std::tuple`) – Some programmer dude Mar 25 '21 at 08:58
  • 1
    @Someprogrammerdude or `struct meaningful_name { int meaningful; int name; };` – Caleth Mar 25 '21 at 09:16

1 Answers1

1

The problem is that you cannot use 2 compare functions and sort it twice, that will revert the first sort. Why don't you do it in 1 step?

bool sor_col(const vector<int> &v1, const vector<int> &v2){
    if(v1[0]>v2[0]) return true;
    if(v1[0]<v2[0]) return false;
    return v1[1]<v2[1];
}

Sorting for the first value in decreasing order and when they are equal, sorting for the second value in increasing order.

The full example:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool sor_col(const vector<int> &v1, const vector<int> &v2){
    if(v1[0]>v2[0]) return true;
    if(v1[0]<v2[0]) return false;
    return v1[1]<v2[1];
}
 
int main(){
    int n,x,y;
    cin>>n;
    vector<vector<int>> v(n);
    for(int i=0;i<n;i++){
        cin>>x>>y;
        v[i].push_back(x);
        v[i].push_back(y);
    }
    sort(v.begin(),v.end(),sor_col);
    for (const auto& vec: v)
    {
        for (const auto& integer: vec)
            cout << integer << ' ';
        cout << endl;
    }
    return 0;
}

https://ideone.com/RRhkn4

Your first sort function has another problem: for v1[0] != v2[0] it returns false, so a vector with 3 5 is not less than a vector with 4 3, but also the second is not less than the first, so they are equal, which they are not.

mch
  • 9,424
  • 2
  • 28
  • 42