Ana Tayffy
Ana Tayffy

Reputation: 39

How to sort a set of pairs?

How shall I use the qsort function to sort a set of pairs ? This is my set :

set< pair< int, int> > my_set                        

This I guess should be my compare function:

int compare (const void * a, const void * b)
{
    return ( *(int*)a - *(int*)b );
}

Should my qsort look like this?

qsort (my_set, no_of_pairs, sizeof(int), compare);

When I sort them I want to sort by the values of a bi-dimensional array **M;, where

 M[my_set.first][my_set.second] = the_value 

Upvotes: 2

Views: 4362

Answers (2)

F&#233;lix Cantournet
F&#233;lix Cantournet

Reputation: 1991

First, prefer std::sort to qsort with c++ std containers. Secondly, you cannot sort a std::set a posteriori. std::set is sorted. You can however specify a custom sorting for the std::set at instanciation using a 2nd template parameter. Refer to the specs.

What you could do, if you need to sort the data after the fact, is use a std::vector instead. There is an algorithm that will cull the duplicate value.

This proposed solution assumes M is some global variable.

#include <algorithm>

bool less_than(const std::pair<int, int> &some, const std::pair<int, int> &other) {
    return M[some.first][some.second] < M[other.first][other.second]; 
}

std::sort(yourvector.begin(), yourvector.end(), less_than);

If M isn't a global variable, you could do something like that :

struc Compair { // see what I did there ? #sofunny
    bool operator() (const std::pair<int, int> &some, const std::pair<int, int> &other) {
        return M[some.first][some.second] < M[other.first][other.second]; 
    }
    int **M;
}

then in main :

Compair mycomparefunctor;
mycomparefunctor.M = arr; // arr is the original int **
std::sort(yourvector.begin(), yourvector.end(), mycomparefunctor);

EDIT :

If you must use a std::set then you should define the custom ordering when you declare it, like so :

Compair mypredicate;
mypredicate.M = arr; // arr is the original int **

std::set<std::pair<int, int>, mypredicate> myset;
// add stuff to the set. They will be sorted following your predicate.

Be careful though : in a set you cannot add 2 items that compare equal. So if your int ** 2D array has several values that are equal, you won't be able to have several pairs corresponding to indexes of equal value in the set.

Upvotes: 1

Bill Lynch
Bill Lynch

Reputation: 81936

You're going about this fairly wrong.

Let's assume that we know the maximum value for each member of the pair. If you don't know this, then you need to figure it out. I'm going to assume that it is 100.

Then all we need to do is iterate over the set, and insert them into the new array. There's no faster way to go about this.

int M[100][100] = {};
for (auto const & pair : my_set)
    M[pair.first][pair.second] = the_value;

Upvotes: 0

Related Questions