C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

std:sort() and custom iterator

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
dipa
Guest





PostPosted: Tue Aug 30, 2005 12:31 pm    Post subject: std:sort() and custom iterator Reply with quote



Two arrays A[] and B[], same size, logically elements (A[i] -> B[i]) are
connected .
I need to sort A and still keep connection with B.
I don't want to create any extra arrays.
My goal is like this:
/////////////////////////////////////////////////////////////
long a[] = {3, 7, 5, 1, ..};
long b[] = {3, 7, 5, 1, ..};

my_iterator<my_pair> it_begin(a, b, 0);
my_iterator<my_pair> it_end(a, b, len);
std::sort(it_begin, it_end);
////////////////////////////////////////////////////////

I've almost working code.
VC 2003 std::sort() works as expected, but std::stable_sort().
g++ (GCC) 3.3.6 not sorting at all.

What is wrong?
Thanks,
Dima

-------------------------------------------------------------
//#include "stdafx.h"
#include <vector>
#include <algorithm>
struct my_pair
{
long &_a, &_b;
long _xa, _xb;
my_pair(long& a, long& b):_a(a), _b(b), _xa(_a), _xb(_b){}
//my_pair(const my_pair& c):_a(c._a), _b(c._b), _xa(_a), _xb(_b){}
const my_pair& operator = (const my_pair& c)
{
_a = c._xa;
_b = c._xb;
_xa = _a;
_xb = _b;
return *this;
}
};
template <typename _T>
class it
{
public:
typedef std::random_access_iterator_tag iterator_category;
typedef _T value_type;
typedef int difference_type;
typedef difference_type distance_type; // retained
typedef _T* pointer;
typedef _T& reference;
//typedef my_pair_r reference;
protected:
long _pos;
long* _a;
long* _b;
public:
it():_a(NULL), _b(NULL),_pos(-1){}
it(long *a, long *b, long pos):_pos(pos), _a(a), _b(b){}
it(const it& c):_pos(c._pos), _a(c._a), _b(c._b){}
public:
it operator-(difference_type d){ return it(_a, _b, _pos - d); }
it operator+(difference_type d){ return it(_a, _b, _pos + d);}
const it& operator+=(difference_type d){ _pos+=d; return *this; }
const it& operator-=(difference_type d) { _pos-=d; return *this; }
difference_type operator-(const it& c) { return _pos - c._pos; }
bool operator<(const it& c) const { return _pos < c._pos; }
bool operator>(const it& c) const { return _pos > c._pos; }
bool operator==(const it& c) const { return _pos == c._pos; }
bool operator!=(const it& c) const { return _pos != c._pos; }
const it& operator--() { _pos--; return *this; }
it operator--(int) { return it(_a, _b, _pos--); }
const it& operator++() { _pos++; return *this; }
it operator++(int) { return it(_a, _b, _pos++); }
value_type operator*() const { return value_type(_a[_pos], _b[_pos]);}
};

bool my_cmp(const my_pair& a, const my_pair& b)
{
return a._a < b._a;
}

int main(int argc, char* argv[])
{
long a[] = {3, 7, 5, 1, 23, 15, 88, 44, 11, 32, 33, 11, 18, 14, 16, 22,
3, 7, 5, 1, 23, 15, 88, 1, 11, 32, 16, 11, 18, 14, 16, 22, 55, 0};
long b[] = {3, 7, 5, 1, 23, 15, 88, 44, 11, 32, 33, 11, 18, 14, 16, 22, 3,
7, 5, 1, 23, 15, 88, 1, 11, 32, 16, 11, 18, 14, 16, 22, 55, 0};
long len = sizeof(a)/sizeof(*a);
it it<my_pair> end(a, b, len);
std::stable_sort(begin, end, my_cmp);
//std::sort(begin, end, my_cmp);
for (long i = 0; i < len; i++)
printf("a[%i]=%itb[%i]=%inr", i, a[i], i, b[i]);
return 0;
}



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Edson Manoel
Guest





PostPosted: Tue Aug 30, 2005 9:58 pm    Post subject: Re: std:sort() and custom iterator Reply with quote



I'm not sure if this is the cause of your problem, but I think your
your Random Access Iterator is incomplete. It must be mutable and
assignable too.

Try using boost::zip_iterator or try debugging inside the stable_sort
algorithm!

Regards


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joel Eidsath
Guest





PostPosted: Wed Aug 31, 2005 2:51 pm    Post subject: Re: std:sort() and custom iterator Reply with quote



Is there a reason that you aren't using a map<int, int>?

Here is some code that will do everything your code does. I just kept
the array for input. You'll probably want to ditch it.

#include <iostream>
#include <map>
#include <utility>

using namespace std;

int main(void){
int a[] = {3, 7, 5, 1, 23, 15, 88, 44, 11, 32, 33, 11, 18, 14, 16, 22,
3, 7, 5, 1, 23, 15, 88, 1, 11, 32, 16, 11, 18, 14, 16, 22, 55, 0};
int len = sizeof(a)/sizeof(*a);

map<int,int> m;
for (int i=0; i< len; ++i){
m[i] = a[i];
}

map for (mP = m.begin(); mP != m.end(); ++mP){
cout << (*mP).first << " " << (*mP).second << endl;
}
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joel Eidsath
Guest





PostPosted: Wed Aug 31, 2005 9:05 pm    Post subject: Re: std:sort() and custom iterator Reply with quote

That's the second time I've made that mistake this week: multimap
should be used, not map


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
dipa
Guest





PostPosted: Thu Sep 01, 2005 9:13 am    Post subject: Re: std:sort() and custom iterator Reply with quote

I need 2 separate arrays for direct access.
They are very huge and I don't want to allocate extra memory for any
supporting vector, map, multimap, and etc.

Recently, I've found mistake in comparison function:
bool my_cmp(const my_pair& a, const my_pair& b)
{
return a._a < b._a;
it should be
return a._xa < b._xa;
}


VC - sort() and stable_sort() are OK.
GCC (3) - sort() is OK but stable_sort().


"Joel Eidsath"
Quote:
Is there a reason that you aren't using a map<int, int>?

Here is some code that will do everything your code does. I just kept
the array for input. You'll probably want to ditch it.

#include <iostream
#include #include
using namespace std;

int main(void){
int a[] = {3, 7, 5, 1, 23, 15, 88, 44, 11, 32, 33, 11, 18, 14, 16, 22,
3, 7, 5, 1, 23, 15, 88, 1, 11, 32, 16, 11, 18, 14, 16, 22, 55, 0};
int len = sizeof(a)/sizeof(*a);

map for (int i=0; i< len; ++i){
m[i] = a[i];
}

map for (mP = m.begin(); mP != m.end(); ++mP){
cout << (*mP).first << " " << (*mP).second << endl;
}
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Fri Sep 02, 2005 4:38 pm    Post subject: Re: std:sort() and custom iterator Reply with quote

On 1 Sep 2005 05:13:43 -0400, "dipa" <kvartira (AT) hotmail (DOT) com> wrote:

Quote:
Recently, I've found mistake in comparison function:
bool my_cmp(const my_pair& a, const my_pair& b)
{
return a._a < b._a;
it should be
return a._xa < b._xa;
}

The real problem is the name of my_pair. It should be
I_can_not_decide_whether_i_am_a_value_or_a_proxy.

It fails because you really need two classes. Since you
are templating the iterator, it may as well be on two
types.

Quote:
template

Names starting with an underscore and followed by an upper
case letter are reserved for the implementation. That is
why you see them in standard template classes. Do not use
them in yours unless you consider yourself the implementation.

template
Quote:
typedef _T value_type;
typedef std::pair<F, S> value_type;


Quote:
typedef _T& reference;
//typedef my_pair_r reference;

Your thought was right. You do need a reference class.
May as well nest it in the iterator.

struct reference {
F& first;
S& second;
reference (F& first, S& second) : first(first), second(second) {
}
operator value_type () const {
return value_type(first, second);
}
reference& operator= (value_type const& rhs) {
first = rhs.first;
second = rhs.second;
}
reference& operator= (reference const& rhs) {
first = rhs.first;
second = rhs.second;
}
};

Quote:
long* _a;
long* _b;
F* _a;

S* _b;

And other places where long was used.

Quote:
value_type operator*() const { return value_type(_a[_pos], _b[_pos]);}
reference operator*() const { return reference(_a[_pos], _b[_pos]);}


May as well tempate the compare function.

template <class F, class S>
bool my_cmp (std::pair<F, S> const& lhs, std::pair<F, S> const& rhs) {
return lhs.first < rhs.first;
}

You may want to investigate boost as a possible solution to some
remaining problems which will not show in your test.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
dipa
Guest





PostPosted: Sat Sep 03, 2005 6:51 pm    Post subject: Re: std:sort() and custom iterator Reply with quote

John,
Thank you for very helpful suggestion.

Quote:
I_can_not_decide_whether_i_am_a_value_or_a_proxy.
True:) That why I'm asking for help.


Unfortunately, VC++ implementation of std::iter_swap()->swap() is not using
"value_type" as tmp value.
/////////
template<class _Ty> inline void swap(_Ty& _Left, _Ty& _Right)
{
_Ty _Tmp = _Left;
_Left = _Right, _Right = _Tmp;
}
////////

"I_can_not_decide" score:
VC.NET GCC (3)
-----------------------------------------
sort() OK OK
stable_sort() OK FAIL
-----------------------------------------

New score:
VC.NET GCC (3)
-----------------------------------------
sort() FAIL OK
stable_sort() OK OK
-----------------------------------------

Thanks,
Dmitry




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Tue Sep 06, 2005 4:03 pm    Post subject: Re: std:sort() and custom iterator Reply with quote

On 3 Sep 2005 14:51:40 -0400, "dipa" <kvartira (AT) hotmail (DOT) com> wrote:

Quote:
Unfortunately, VC++ implementation of std::iter_swap()->swap() is not using
"value_type" as tmp value.

Try overloading it for your type.

template <class F, class S>
void iter_swap (it<F, S> a, it<F, S> b) {
typename it<F, S>::value_type t(*a);
*a = *b;
*b = t;
}

Quote:
"I_can_not_decide" score:
VC.NET GCC (3)
-----------------------------------------
sort() OK OK
stable_sort() OK FAIL
-----------------------------------------

New score:
VC.NET GCC (3)
-----------------------------------------
sort() FAIL OK
stable_sort() OK OK
-----------------------------------------

Do we have a better score?

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Dmitry
Guest





PostPosted: Wed Sep 07, 2005 1:04 am    Post subject: Re: std:sort() and custom iterator Reply with quote

Quote:
Try overloading it for your type.
I already did, but it works only if iter_swap declared as the member of std

namespace.
Anyway, problem is solved.

Thanks,
Dmitry




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.