Read one array into another then sort it = Newbie problem!

T

TreatmentPlant

All,

As a relative newbie to the C++ world, I am struggling with a project,
and ask some assistance please.

I would like to progressively read the contents of one array into
another array, sort the new array, return the median value and then add
the next element of the source array, sort the new array etc etc...

what I have so far... (extract)

//l_iMaxRecords is the number of elements in the OriginalArray
for(int i=0; i<l_iMaxRecords;i++)
{
float* l_fTempDataArray=new float;

for(int x=0;x<=i;x++)
l_fTempDataArray[x]=OriginalArray[x];

//I need to sort this array
sort(l_fTempDataArray);

if(i%2==1)
return l_fTempDataArray[(i+1)/2];
else
return (l_fTempDataArray[i/2]+l_fTempDataArray[(i+1)/2])/2;
}


Hopefully this will make sense to you and will be able to assist. You
might be able to tell, I need a lot of help in sorting this one out
(maybe this time I have bitten off more than i can chew?)


TIA
 
O

osmium

TreatmentPlant said:
As a relative newbie to the C++ world, I am struggling with a project, and
ask some assistance please.

I would like to progressively read the contents of one array into another
array, sort the new array, return the median value and then add the next
element of the source array, sort the new array etc etc...

what I have so far... (extract)

//l_iMaxRecords is the number of elements in the OriginalArray
for(int i=0; i<l_iMaxRecords;i++)
{
float* l_fTempDataArray=new float;

for(int x=0;x<=i;x++)
l_fTempDataArray[x]=OriginalArray[x];

//I need to sort this array
sort(l_fTempDataArray);

if(i%2==1)
return l_fTempDataArray[(i+1)/2];
else
return (l_fTempDataArray[i/2]+l_fTempDataArray[(i+1)/2])/2;
}


Hopefully this will make sense to you and will be able to assist. You
might be able to tell, I need a lot of help in sorting this one out (maybe
this time I have bitten off more than i can chew?)


You can use qsort() to sort an array. It is in <cstdlib>. You will need
some minimal ability to handle function pointers as you will have to write a
compare function and tell qsort() how to find this function.

The compare function has this signature:

int cmp(const void*, const void*)
You will be doing some casts in the code you write, probably cast void to
float..

Note that this matches the last parameter required by qsort(). So the call
becomes:

qsort(...., cmp)

The sort is done in place.

No, I don't think you have bitten off too much. There might be better ways
to do what you want, but it sounds like something you can do.
 
O

osmium

osmium said:
int cmp(const void*, const void*)
You will be doing some casts in the code you write, probably cast void to
float..

void pointer to float pointer
 
J

Jerry Coffin

01.iinet.net.au>, (e-mail address removed)
says...

[ ... ]
I would like to progressively read the contents of one array into
another array, sort the new array, return the median value and then add
the next element of the source array, sort the new array etc etc...

This sounds like a rather odd requirement, but if it's
really what you need, you're probably better off just
inserting the new elements in the correct place.

I'd also use std::vector instead of arrays -- especially
in a situation like there were one is going to be
expanding as you use it, the memory management that
std::vector does for you will almost certainly be very
helpful.

It's also worth noting that there's already an algorithm
in the standard library for finding the nth element of a
collection. The primary advantage of this is speed.
Rather than sorting the whole collection, it sorts the
collection only enough to find the required element.
//l_iMaxRecords is the number of elements in the OriginalArray
for(int i=0; i<l_iMaxRecords;i++)
{
float* l_fTempDataArray=new float;


As it stands, this is leaking memory. You're allocating
memory each time you enter the loop, but never releasing
the memory again.

[ ... ]
Hopefully this will make sense to you and will be able to assist. You
might be able to tell, I need a lot of help in sorting this one out

Nice pun. :)
(maybe this time I have bitten off more than i can chew?)

Oh, I doubt it. Right now your memory management has
problems, but you're pretty close on the basic algorithm.
 
T

TreatmentPlant

<snip>

Thanks Jerry,

This is where I am up to now - but I still have some errors. May I
indulge you again?

The code:

for(int i=0; i<=l_iMaxRecords;i++)
{
vector<float> v;//a one dimensional vector

for(int x=0;x<=i;x++)
v.push_back(OriginalArray[x]);

//sort the vector
sort(v.begin(), v.end());

if(i%2==1)
a_psResultRec->psResultArray->pfValue=v.at((i+1)/2);
else
a_psResultRec->psResultArray->pfValue=(v.at(i/2) + v.at((i/2)+1))/2;

//empty the vector
v.clear()
}

The output is going to an array, but I get the following errors and
cannot think my way around them...

Compiling...
Statistics.cpp
C:\Statistics.cpp(172) : error C2440: '=' : cannot convert from 'float'
to 'float *'
There is no context in which this conversion is possible
C:\Statistics.cpp(174) : error C2440: '=' : cannot convert from 'float'
to 'float *'
There is no context in which this conversion is possible
Error executing cl.exe.

Statistics.dll - 2 error(s), 0 warning(s)



How can I cast float v.at((i+1)/2) to float * v.at((i+1)/2) ???

Or am I missing something??

Thanks again,


Scott
 
T

TreatmentPlant

<snip>

[EDITED - Corrected Version]

Thanks Jerry,

This is where I am up to now - but I still have some errors. May I
indulge you again?

The code:

for(int i=0; i<=l_iMaxRecords;i++)
{
vector<float> v;//a one dimensional vector

for(int x=0;x<=i;x++)
v.push_back(OriginalArray[x]);

//sort the vector
sort(v.begin(), v.end());

if(i%2==1)
a_psResultRec->psResultArray->pfValue=v.at((i+1)/2);
else
a_psResultRec->psResultArray->pfValue=(v.at(i/2) + v.at((i/2)+1))/2;

//empty the vector
v.clear()
}

Now that I have fixed that minor ommission (with major consequences!)
the dll compiles, but when I run it I get these errors:

First-chance exception in MSXTest.exe (KERNEL32.DLL): 0xE06D7363:
Microsoft C++ Exception.
First-chance exception in MSXTest.exe (KERNEL32.DLL): 0xE06D7363:
Microsoft C++ Exception.

Any ideas?

Thanks again,


Scott
 
J

Jerry Coffin

01.iinet.net.au>, (e-mail address removed)
says...
<snip>

Thanks Jerry,

This is where I am up to now - but I still have some errors. May I
indulge you again?

Sure. Just FWIW, questions like this are usually easier
to answer if you provide a minimal piece of code that can
be compiled as-is, but still demonstrates the problem
you're having.

[ ... ]

I'm guessing these lines:
a_psResultRec->psResultArray->pfValue=v.at((i+1)/2);
else
a_psResultRec->psResultArray->pfValue=(v.at(i/2) + v.at((i/2)+1))/2;

Are what are being referred to by these error message:
Compiling...
Statistics.cpp
C:\Statistics.cpp(172) : error C2440: '=' : cannot convert from 'float'
to 'float *'
There is no context in which this conversion is possible
C:\Statistics.cpp(174) : error C2440: '=' : cannot convert from 'float'
to 'float *'
There is no context in which this conversion is possible

I'm only guessing since I can't see the definition of
a_psResultRec and/or psResultArray, but it looks like
that code is expecting an array of values. This makes
sense: since you're creating (and need to return) a
number of values, you need an array to hold those values.

Here's a rough idea:

std::vector<float> ret_v;
std::vector<float> v;

for (int i=0; i<originalArraySize; ++i) {
v.push_back(OriginalArray);

std::sort(v.begin(), v.end());

if (i&1)
ret_v.push_back(v[i/2]);
else
ret_v.push_back(v[i/2] + v[i/2+1]/2);
}

float *temp = new float[ret_values.size()];
std::copy(ret_v.begin(), ret_v.end(), temp);
a_psResultRec->psResultArray->pfValue = temp;

If you can rewrite the surrounding code, you could change
pfValue to be a vector<float> instead of a pointer to a
float -- that would simplify this code, and probably make
memory management quite a bit simpler. As it stands, this
code is basically an open invitation to memory leakage.
Depending on how much other code manipulates/plays with
pfValue, that rewrite might be trivial or it might be a
truly massive and horrendous undertaking...
 
T

TreatmentPlant

<snip>

and with a little more testing, the error is being generated somewhere
in these lines:

sort(v.begin(), v.end());
if(i%2==1)
a_psResultRec->psResultArray->pfValue=v.at((i+1)/2);



Have I got the sort term right?
 
T

TreatmentPlant

Jerry,

Thanks for you attempts to help me... but even you couldn't help me from
being a numpty.

The answer was staring me in the face all the time.

The problem wasn't with the code, it was with the logic!


if(i%2==1)
a_psResultRec->psResultArray->pfValue=v[((i+1)/2)-1];
else
a_psResultRec->psResultArray->pfValue=(v[(i/2)-1] + v[(i/2)])/2;


Its late here, I have been up (literally) all night.... but now I will
sleep well.


Thanks you again for your effort.
 
M

Markus Schoder

TreatmentPlant said:
<snip>

[EDITED - Corrected Version]

Thanks Jerry,

This is where I am up to now - but I still have some errors. May I
indulge you again?

The code:

for(int i=0; i<=l_iMaxRecords;i++)
{
vector<float> v;//a one dimensional vector

for(int x=0;x<=i;x++)
v.push_back(OriginalArray[x]);

//sort the vector
sort(v.begin(), v.end());

if(i%2==1)
a_psResultRec->psResultArray->pfValue=v.at((i+1)/2);
else
a_psResultRec->psResultArray->pfValue=(v.at(i/2) + v.at((i/2)+1))/2;


v.at((i/2)+1) throws for i == 0 as (i/2)+1 == 1 and v contains only one
element at index 0.

I think the logic is wrong. Since your vector contains i + 1 elements
you have to invert the if statement.
//empty the vector
v.clear()

clear() is unneeded here as v goes out of scope anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top