need help for STL sort inside a class

Write here if you have problems with your C++ source code

Moderator: Board moderators

Post Reply
menghiot
New poster
Posts: 4
Joined: Fri Sep 23, 2005 6:57 am

need help for STL sort inside a class

Post by menghiot » Thu Jan 26, 2006 12:09 pm

Hi, i tried to sorting an array a, with a condition s[a] <= s[a[j]] (i<j), s is given. Both a and s is contained inside a class. You can take a look at the sample source code.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class gg{
public:

bool cmp( int a, int b)
{
return s[a]<s;
}


gg(){
for(int i=0; i<20; i++)
s.push_back(i);

random_shuffle(s.begin(), s.end());
for(int i=0; i<20; i++)
a.push_back(i);
random_shuffle(a.begin(), a.end());

sort(a.begin(), a.end(), cmp );

}
vector< int > s;
vector< int > a;
};

int main()
{
gg tmp;
}




My problem is that it cannot compile. CAN ANYONE HELP ME?

mamun
A great helper
Posts: 286
Joined: Mon Oct 03, 2005 1:54 pm
Location: Bangladesh
Contact:

Post by mamun » Thu Jan 26, 2006 1:21 pm

The compare function should be declared outside and before the class gg; and it should be something like this

Code: Select all

bool cmp(int a, int b) {
	return a < b;
}

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Thu Jan 26, 2006 7:34 pm

If you really want to encapsulate the comparator inside a class, you should use a function object instead of a function (which is a method in this case and thus cannot be used by sort directly). Just create an inner class with a public operator() overloaded for the type you want to compare and then use an instance of that class as the comparator when calling sort.
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

menghiot
New poster
Posts: 4
Joined: Fri Sep 23, 2005 6:57 am

Post by menghiot » Fri Jan 27, 2006 1:18 pm

Hi ,

I, actually, did all the methods which you mention, before I post the questions . what I tried to do is sorting array a with condition :
s[a] < s[a[j]] (i<j) , not a<a[j] , (i<j) ....

if I declare a inner class like

class gg{
public:

class cmp{
public:
bool operator()(int a, int b)
{
return s[a]<s;
}
};

.....
};

cmp class is not able to see vector<int> s;

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Fri Jan 27, 2006 5:30 pm

There are plenty of solutions to your problem, but I believe that the best one is to change design - it seems there's something terribly wrong with it. If elements of a and s are so related, you might think of using a separate class for them.

Anyway, if you just want to stick with two vectors, you can try something like this:

Code: Select all

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct foo{
    vector<int> a;
    vector<int> s;

    struct cmp{
        static vector<int> * sref;

        bool operator()(int x, int y)const{
            return ((*sref)[x] < (*sref)[y]);
        }
    };

    void perform(){
        cmp comparer;
        comparer.sref = &s;

        sort(a.begin(), a.end(), comparer);
    }
};

vector<int> * foo::cmp::sref;

int main(){
    foo bar;
    bar.perform();
}
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

menghiot
New poster
Posts: 4
Joined: Fri Sep 23, 2005 6:57 am

Post by menghiot » Sat Jan 28, 2006 4:47 am

:D Many thanks !

Quantris
Learning poster
Posts: 80
Joined: Sat Dec 27, 2003 4:49 am
Location: Edmonton AB Canada

A comment

Post by Quantris » Sun Feb 26, 2006 10:09 pm

I tend to prefer something like:

Code: Select all

struct sortBy {
  const vector<int> &key;
  sortBy(const vector<int> &S) : key(S) {}
  bool operator()(int a, int b) const {
    return key[a] < key[b];
    }
  };
and then you can use sort(a.begin(), a.end(), sortBy(s));

This is just a bit more modular so you can apply it to vectors that aren't in a class (you can generalise more and pass it a function that assigns a key value to the sorted elements, or template the sortBy structure, etc.)

However, I have to agree with Krzysztof Duleba -- it is probably better to keep a and s as a vector of pairs or something to make it simpler (and also you get to keep the a value and s value at the same location).

Post Reply

Return to “C++”