best result function

J

John J

I've written the following code into a class to search for and display the
results of all races entered (The complete code is in a previous thread). I
wish to amend the code so as to display the best result only.



Can anyone suggest a simple amendment to the following that will result in
only the best result being displayed?



Thanks for any help





void Yacht::best_result (ostream& out) const

{

Entry* e =NULL;

out << "A search of races for this Yacht shows the following results:
" << endl;

if (nYEntries == 0)

{

out << "This Yacht has entered no races: " << endl;

}

else

{

bool found_a_result = false; // no result found yet

for (int i=0; i<nYEntries; i++)

{

e = yacht_entries;

if (e->getPlace() >= 1)

{

out << *e;

found_a_result = true; // a result has been found

}

}

if (!found_a_result) // if no result

{

out << "No results were found" << endl;

}

}

}
 
J

John Harrison

John J said:
I've written the following code into a class to search for and display the
results of all races entered (The complete code is in a previous thread). I
wish to amend the code so as to display the best result only.

This is where you have to imagine yourself as a computer. If you where a
computer and were given a list of results how would you find the best one?

Remembering that a computer can only look at the result one at a time, the
important concept is that of the 'best result so far'. While the computer is
looking at each result in turn it can remember the best result so far. Use a
variable to store the best result so far. When the computer has looked at
all the results, the best result so far will be the best result overall.

HTH
john
 
J

John J

I've amended the code a couple of times; however, whenever I try and output
the new value, I either get a numberical value (rather than the Entry Object
I wish returned) or a series of link errors.

I'm doing my amendments after the test (e->getPlace() >=1) and assigning *e
to a variable "bestplace" in the same if loop. Am I going about this
incorrectly?

Thanks
 
K

Karl Heinz Buchegger

John said:
I've amended the code a couple of times; however, whenever I try and output
the new value, I either get a numberical value (rather than the Entry Object
I wish returned) or a series of link errors.

I'm doing my amendments after the test (e->getPlace() >=1) and assigning *e
to a variable "bestplace" in the same if loop. Am I going about this
incorrectly?

Nobody knows, if you don't show the code which gives you troubles.

Besides. If you want to ask the same question in more then
one newsgroup, do a crosspost. This way people in the other
group will see the answers and don't have to answer an already
answered question in another newsgroup.
 
J

John J

OK, I'm now beating my head against my desk. If anyone can help with some
code and an explanation of how it works I'd be highly appreciative.

Every attempt I've had compiles with conversion errors and I've got so may
"commented out" lines I can't even make sense of it any longer.

Thanks for any help
 
B

Buster

John said:
OK, I'm now beating my head against my desk. If anyone can help with some
code and an explanation of how it works I'd be highly appreciative.

You didn't define the problem well, but here goes. I think it's
pretty self-explanatory. Let us know if you're still having trouble.

#include <algorithm>
#include <ostream>

struct better_entry
{
bool operator () (Entry * x, Entry * y)
{
return x->getPlace () >= 1 &&
y->getPlace () < 1 ||
x->getPlace () < y->getPlace ();
}
};

void Yacht::best_result (std::eek:stream & out) const
{
if (yacht_entries.empty ())
{
out << "This yacht has entered no races.\n";
}
else
{
if (Entry * best_entry = * std::min_element
(yacht_entries.begin (), yacht_entries.end (),
better_entry ()))
{
// Print details about best_entry.
}
else
{
out << "No results were found.\n";
}
}
}
 
J

John J

Ok, below is my latest attempt at this, could someone please give me an idea
of what I'm doing wrong.



Thanks for the help offered so far by people; however, I don't wish to make
any changes to other constructors, functions etc. I'd prefer to simply
correct my function. I realise it's not the ideal solution; however, I
understand most of what it's doing (unfortunately not all).



I appologise for the format, I've tried a cut and paste through word to get
rid of excessive white space; however, the end result still isn't perfect.



Thanks for any help







//Display the best result of a Yacht in all entered races

void Yacht::best_result (ostream& out) const

{

Entry* e =NULL;

out << "A search of races for this Yacht shows the following results: " <<
endl;



if (nYEntries == 0)

{

out << "This Yacht has entered no races: " << endl;

}



else

{

bool found_a_result = false; // no result found yet

for( int i = 1; i < nYEntries; i++ )



{

Entry* best_result = yacht_entries[0];

if (yacht_entries->getPlace() < best_result->getPlace())

best_result = yacht_entries;



{

cout << "Best result was " << best_result;

}

}



if (!found_a_result) // if no result

{

cout << "No results were found" << endl;

}

}



}
 
D

David Rubin

John said:
I've written the following code into a class to search for and display the
results of all races entered (The complete code is in a previous thread). I
wish to amend the code so as to display the best result only.
Can anyone suggest a simple amendment to the following that will result in
only the best result being displayed?

[snip - rearranged]
void Yacht::best_result (ostream& out) const
{
Entry* e =NULL;

out << "A search of races for this Yacht shows the following results: "
<< endl;

if (nYEntries == 0)
{
out << "This Yacht has entered no races: " << endl;
}
else
{
bool found_a_result = false; // no result found yet
for (int i=0; i<nYEntries; i++)
{
e = yacht_entries;
if (e->getPlace() >= 1)
{
out << *e;
found_a_result = true; // a result has been found
}
}
if (!found_a_result) // if no result
{
out << "No results were found" << endl;
}
}
}


Firstly, please try to fix your whitespace after you cut-and-paste code
into your news client.

Secondly, this is not a very nice function to put into you class
interface. Typically, you would have an accessor which simply returns
the best result rather than printing out a bunch of stuff. That way, you
can use it in many different situations. The function which would do
what you are doing above would be a free function--not part of you class
interface, but part of your program. You should approach C++ programs
(and more generally OO programs, and even non-OO programs) as creating
*components* and the programs which use them.

Thus, your Yacht class might have a function such as

const Entry& Yacht::best_result() const;
// Return a pointer to the best result for this Yacht, or
// a null pointer if this Yacht is not a participant in any
// events.

Your *program* might have a function

void showBestResult(std::eek:stream& out, const Yacht& y)
{
const Entry& e = y.best_result();

out << (e == 0) ? "This yacht has entered no races." : e
<< std::endl;
}

A function which shows all results is a little more difficult because
you need to 1) externalize the yacht_entries implementation, 2) create a
friend function, 3) create a member function, or 4) create a means for
iterating over yacht_entries.

The situation here is rather difficult since you've designed several
cyclic dependancies into your class hierarchy:

http://groups.google.com/[email protected]&oe=UTF-8&output=gplain

+-------+ +-------+ +------+
| Yacht +----o Entry +----o Race |
+---o---+ +--+-+--+ +---o--+
| | | |
+-----------+ +-----------+

You may be better served by a class hierarchy such as

Race +----o Entry +---o Yacht

and functions such as

void showBestResult(std::eek:stream& out,
const Yacht& y,
const RaceList& list);

void showAllResults(std::eek:stream& out,
const Yacht& y,
const RaceList& list);

where, for example,

typedef std::deque<Race> RaceList;

/david
 
J

John Harrison

John J said:
I've amended the code a couple of times; however, whenever I try and output
the new value, I either get a numberical value (rather than the Entry Object
I wish returned) or a series of link errors.

I'm doing my amendments after the test (e->getPlace() >=1) and assigning *e
to a variable "bestplace" in the same if loop. Am I going about this
incorrectly?

Seems unlikely, I don't see how 'e->getPlace() >=1' corresponds to the 'best
place found so far'. To find the best place so far, you must compare the
place you are looking at now, with the best place found so far. Also I don't
think you should assign *e, you should stick with pointers.

I.e. something like (inside a loop)

if (e->getPlace() < bestSoFar->getPlace())
{
bestSoFar = e;
}

But of course as usual there is more detail to get exactly right.

I would not advise doing this by amending existing code, write the function
from scratch. It really is only a few lines.

john
 
K

Karl Heinz Buchegger

John said:
Ok, below is my latest attempt at this, could someone please give me an idea
of what I'm doing wrong.

Man. If you are going to use my code posted in
alt.comp.lang.learn.c-c++
then at least you could use the code provided by me.
and of course you could think about this code works.
 
J

John Harrison

John J said:
Ok, below is my latest attempt at this, could someone please give me an idea
of what I'm doing wrong.

You need to think carefully about your code, as I said before it has to be
exactly right. The code you have is nearly right.

Look at the statement

Entry* best_result = yacht_entries[0];

Do you really what to execute that each time you go around the for loop? Or
do you want to execute it once before you go into the for loop?

Now look at this statement

cout << "Best result was " << best_result;

Do you really want to execute that statement each time you go round the
loop? Or do you want to execute it once after you finished the for loop.

Think about it, outputing "Best result was ..." before you have finished the
for loop cannot POSSIBLY be right because before you have finished the for
loop you haven't even looked at all the entries yet.

Finally think again about this

cout << "Best result was " << best_result;

What is best_result? It's a pointer of course. Do you want to output a
pointer value? No you want to output what it is pointing at (I presume). So
you need something like this

cout << "Best result was " << *best_result;

or perhaps more likely this

cout << "Best result was " << best_result->getPlace();

john
//Display the best result of a Yacht in all entered races
void Yacht::best_result (ostream& out) const
{
Entry* e =NULL;
out << "A search of races for this Yacht shows the following results: " <<
endl;
if (nYEntries == 0)
{
out << "This Yacht has entered no races: " << endl;
}
else
{
bool found_a_result = false; // no result found yet
for( int i = 1; i < nYEntries; i++ )
{
Entry* best_result = yacht_entries[0];
if (yacht_entries->getPlace() < best_result->getPlace())
best_result = yacht_entries;
{
cout << "Best result was " << best_result;
}
}



if (!found_a_result) // if no result

{

cout << "No results were found" << endl;

}

}



}
 
K

Karl Heinz Buchegger

John said:
You need to think carefully about your code, as I said before it has to be
exactly right. The code you have is nearly right.

This is what I have posted 2 and a half hours ago in alt.comp.lang.learn.c-c++
(where John J has opened the very same thread):

Seems John J. is unable to understand the explanation of how this
should work, nor is he able to cur&paste presented code into
his project

--------------------------------------------------------------------------------

you want to do:

use a loop to figure out which one is the best result

after the loop: print the found best result

as for the part: use a loop to figure out ...
You do it this way: You use a variable to hold the best
result found so far (initialized to some proper value).
In the loop you then compare the result of the Entry in
question with best result so far. If that one is better,
you have a new best result so far. You just need to
remember where you found that new best result.

Once the loop has finished, you then know where you have found
the overall best result. This is the usual looping structure
used to find a minimum or maximum. If you think of it, it is
something you have done thousends of time in real life also.


in code:

Entry* best_result = yacht_entries[0];

for( int i = 1; i < nYEntries; i++ )
{
if( yacht_entries->getPlace() < best_result->getPlace() )
best_result = yacht_Entries;
}

cout << "Best result was " << best_result->getPlace();
 
J

John J

Karl,

As I said in the other thread thanks but your code doesn't work inside my
class, and yes I did use some of it and yes you're right obviously I don't
understand your explanation, otherwise I wouldn't be asking for further
help.

What seems plain, clear and simple to you may not to someone else. A couple
of weeks ago I didn't even know what a compiler was; however, thanks to some
of the people in this newsgroup I'm learning about c++.
 
K

Karl Heinz Buchegger

John said:
Karl,

As I said in the other thread thanks but your code doesn't work inside my
class

compare what I posted with the thing you posted.
You didn't use what I posted. You used something
that looks close.

If you need to understand something, then a seperate
test program which just concentrates on the topic
you want to understand is sometimes a good idea.

#include <iostream>

int main()
{
int Numbers[] = { 3, 8, 2, 5, 6 };
int Smallest;

Smallest = Numbers[0];

for( int i = 1; i < 5; i++ )
{
if( Numbers < Smallest )
Smallest = Numbers;
}

std::cout << "The smallest number was " << Smallest << std::endl;

return 0;
}

This does exactly the same thing: find the smallest (best)
number in an array of numbers. Use this program and step
it through with your debugger. Understand how it does, what
it does. Then use that knowledge and apply it to your
problem.

When the program starts, Smallest is assigned the value 3, since
Numbers[0] equals 3. Then the loop starts, i gets a value of 1.
The if tests if Numbers, that is Numbers[1], which has the
value 8, is less then Smallest, which has the value 3.
Well. 8 is not less then 3, thus nothing happens. There is
nothing more in the loop body, thus i is incremented, and since
i is less then 5, the loop body is executed again.
The if tests if Numbers[2], value: 2, is less then Smallest (value: 3)
Yes. 2 is less then 3, thus the if body is taken, which assigns
the value of Numbers[2], which happens to be 2, to Smallest, thus
Smallest equals 2 now.
The loop makes one more turn and compares Numbers[3], (value: 5)
with Smallest (value: 2). 5 is not less then 2, thus nothing happens
in the loop.
Next turn through the loop: Compare Numbers[4] (value 6) with
Smallest (value: 2). 6 is not less then 2, thus nothing happens
in the loop body.
The loop is then terminated since i has reached the value 5, which
terminates the loop .... and ....
Smallest contains the smallest value found in the array: 2

HTH
 
B

Bill Seurer

John said:
You need to think carefully about your code, as I said before it has to be
exactly right. The code you have is nearly right.

...good suggestions...

Also, your boolean that keeps track of whether you found a result is
initialized to false but never set to true anywhere.
 
D

David Rubin

David Rubin wrote:

[snip]
Your *program* might have a function

void showBestResult(std::eek:stream& out, const Yacht& y)
{
const Entry& e = y.best_result();

Should be

const Entry *e = y.best_result();

I started with pointers, but changed my mind in the middle of the post.
I was wrong.
out << (e == 0) ? "This yacht has entered no races." : e *e
<< std::endl;
}

/david
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top