Board index » cppbuilder » Function object and std:sort.

Function object and std:sort.


2007-12-26 12:22:56 PM
cppbuilder74
Dear Sir,
Hello,
I wish to sort a two dimensional array but was wondering about the function
object and
sort command;
Here is the array declaration;
struct stringlist{
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];
1 to 11 represents the i elements and 1 to 2000 represents the j elements.
The value filename is always equal for each ith element. Here is example
input data;
stringlist1[0][1].filename = "file2";
stringlist1[0][1].str = 2;
stringlist1[0][1].points = 8;
stringlist1[0][2].filename = "file2";
stringlist1[0][2].str = 1;
stringlist1[0][2].points = 11;
stringlist1[1][1].filename = "file1";
stringlist1[1][1].str = 2;
stringlist1[1][1].points = 8;
stringlist1[1][2].filename = "file1";
stringlist1[1][2].str = 1;
stringlist1[1][2].points = 11;
The i elements and filename values are already in correct order. I wish to
only sort by the jth element str values so the output would be;
stringlist1[0][1].filename = "file2";
stringlist1[0][1].str = 1;
stringlist1[0][1].points = 11;
stringlist1[0][2].filename = "file2";
stringlist1[0][2].str = 2;
stringlist1[0][2].points = 8;
stringlist1[1][1].filename = "file1";
stringlist1[1][1].str = 1;
stringlist1[1][1].points = 11;
stringlist1[1][2].filename = "file1";
stringlist1[1][2].str = 2;
stringlist1[1][2].points = 8;
What would the function object and sort command look like?
Here is my draft;
struct stringlists{
bool operator() (const stringlist& lhs, const stringlist& rhs) const
{
return (lhs.str < rhs.str);
}
};
std::sort(stringlist1 , stringlist1 + 2, stringlists());
Is this correct?
Thankyou,
Regards Digby Millikan.
 
 

Re:Function object and std:sort.

"Digby Millikan" < XXXX@XXXXX.COM >writes:
Quote
struct stringlist{
BTW: That's a misnomer. The name of this struct should denote the
content of one single instance, not of a data structure of instances.
Quote
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];

struct stringlists{
bool operator() (const stringlist& lhs, const stringlist& rhs) const
{
return (lhs.str < rhs.str);
}
};

std::sort(stringlist1 , stringlist1 + 2, stringlists());

Is this correct?
No.
stringlist1's type is 'array of 11 arrays of 2000 stringlist objects each'.
In the invokation of std::sort, this type is implicitly converted to
'pointer to array of 2000 stringlist objects', and the value passed as
first argument points at the first element (the one with index 0) of
the array of 11.
The expression stringlist1+2 has the same pointer type; its value,
passed as second argument to std::sort(), points at the third element
(the one with index 2) of the array of 11.
Now what std::sort() does is dereference these pointers and attempt to
pass the result of the dereferenciation as arguements to
stringlists::operator(). The result of the dereferenciation is of type
'array of 2000 stringlist objects', i.e. stringlist[2000].
stringlists::operator() expects its two arguments to be of type const
stringlist&. There is no implicit conversion from stringlist[2000] to
stringlist, so the compiler doesn't accept the invokation of
stringlists::operator().
I still think that the clean solution to your problem would be to
"flatten out" stringlist1 into a 1dimensional array, e.g.:
stringlist stringlist1[11*2000];
You can get away by lying at the compiler, e.g.:
std::sort(stringlist1[0],stringlist1[2],stringlists());
which relies on the array elements of a 2dimensional array of 11 times
2000 objects being represented in memory as if there was a
1dimensional array of 11*2000 objects. I think that it's safe to rely
on this memory layout, but using a 2dimensional array still obfuscates
your code.
 

Re:Function object and std:sort.

Having the 11 arrays of 2000 really makes things a lot easier elsewhere
in my system, I really wan't to sort it, as it is.
Regards Digby
 

{smallsort}

Re:Function object and std:sort.

"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
struct stringlist{
BTW: That's a misnomer. The name of this struct should denote the
content of one single instance, not of a data structure of instances.
Quote
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];
So how should;
struct stringlist{
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];
read?
 

Re:Function object and std:sort.

Digby Millikan wrote:
Quote
Having the 11 arrays of 2000 really makes things a lot easier elsewhere
in my system, I really wan't to sort it, as it is.
If I read your requirements correctly, you want to sort
the 2000 elements of each of the 11 subarrays idependantly.
How about an 11 member array of 2000 element vectors?
Or write your own sort.
Bubble sorts are extremly easy to write, and 2000 elements
are usually fast enough with bubble.
 

Re:Function object and std:sort.

Hi Digby
Digby Millikan says:
Quote
Dear Sir,
Here is the array declaration;

struct stringlist{
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];

1 to 11 represents the i elements and 1 to 2000 represents the j elements.

The value filename is always equal for each ith element. Here is example
input data;
I sure if You told some more about what You are trying to
accomplish You would be able to get som good advice on
how to do it.
I I understand You correctly You have 11 different
filenames and then 2000 strand points per file
struct TScore
{
int str; //str ususally stands for a string
int points;
TScore():str(0),points(0){}
};
typedef std::vector<TScore>TScoreVec;
struct TFileName
{
TScoreVec Scores(2000);
or
TScore Scores[2000];
String FileName;
};
typedef std::vector<TFileName>TFileVec;
TFileVec Filenames(11);
Filenames[5].Scores[905].Points = SomeInt;
This is just an idea and it is not tested, but a
setup like this can be sorted anyway You like.
Kind regards
Asger
 

Re:Function object and std:sort.

"Digby Millikan" < XXXX@XXXXX.COM >writes:
Quote
>struct stringlist{

BTW: That's a misnomer. The name of this struct should denote the
content of one single instance, not of a data structure of instances.


So how should;

struct stringlist{
AnsiString filename;
int str;
int points;
}stringlist1[11][2000];

read?
I don't know. I just know that a type whose instances are not lists
should not have a name that indicates so.