. 09 Algorithms
. Previous
.See ./08.html
.Open Prepare
. 4.8 Formulating Algorithms: Counter-Controlled Repetition
. 4.9 Formulating Algorithms: Sentinel-Controlled Repetition
. 4.10 Formulating Algorithms: Nested Control Statements
. 4.11 Assignment Operators
. 4.12 Increment and Decrement Operators
.Close Prepare
. Deliver a Question
.Open Answered Questions on algorithms and control structures
. When to use the different kinds of loop -- while for do-while
Everybody agrees that you must use the for loop for counting and
scanning through data. The while is more general purpose and best at
iterative algorithms.
I personally think you should `never` use the "do-while". Just an opinion
based on 30 years experience.... I used them from 1964 through to 1978 and
then abandoned them and started to have fewer bugs.
. Pitfalls of the do-while
Basically having to write code in the do-while that works
whether or not the condition is true.
Also changing a problem with zero-repetitions to one where there must be at
least one repetition.
. What is the purpose of Pseudocode
To be able to think about a solution of a problem without worrying about
the C++ syntax.
. What is the reason for nested control statements
Because we have nested problems, of course:-)
Seriously: In the lab I showed you a program that output a grid of symbols. The structure
is
.(
row
.(
item item item item ...
.)
row
.(
item item item item ...
.)
...
.)
so the only wise way to produce the output is a nested loop.
In general most probems demand a complicated algorithm to solve them... one
where a selection has to be repeated, or where we have to choose between two
loops. We can have solutions where a repeated pattern has to (itself) be repeated.
. Is the member function determineClassAverage a C++ keyword
No. In fact, only keywords that are operators can be redefined as member functions.
Don't do this in CS201!
. Is the member function determineClassAverage assigned a value
No. Functions are not assigned values... you must define them. So
we need to include a definition like this somewhere in our compilation:
.As_is void GradeBook::determineClassAverage()
.As_is {
.As_is //whatever
.As_is }
. Should I use ++ and -- rather than writing the assignment out
Yes!
Don't forget it is simpler to type
.As_is myLongNamedCounter++;
than
.As_is myLongNamedCounter=myLongNamedCounter+1;
. Pre and post increment operators
.Table Before Operation After Value returned
.Row v is v0 v++ v is v0+1 v0
.Row v is v0 ++v v is v0+1 v0+1
.Row v is v0 v+1 v is v0 v0+1
.Row v is v0 v-- v is v0-1 v0
.Row v is v0 --v v is v0-1 v0-1
.Row v is v0 v-1 v is v0 v0-1
.Close.Table
The wise programmer uses "++" and "--" very simply to add and subtract 1 like his
.As_is v++;
and avoids complicated trickery like this:
.As_is v= (++v) * (v--);
which takes a lot of thought to get right and even more thought to figure out.
. Do assignment operators help or just be confusing
Both. It depends on experience and the precise use.
Many people use them and as a result you have to be able to read them.
Usually it does not make much difference. But
when you have a long variable and want to add 2 to it:
.As_is myObject.forExampleAttribute0+=2
it is too easy to mistype the expanded version:
.As_is myObject.forExampleAttribute0= myObject.forExampleAttributeO+2
. If output shows an object to have value zero does it mean it wasn't allocated a value
Not really, it is easy for a variable to become zero as the result of a complex
calculation.
Also -- there is no guarantee that ints and doubles are set to zero initially.
. Can you set a repetition to terminate at any value
Yes.
. Is it better to use a merge symbol in UML for multiple activities
When the UML activity diagram or flowchart shows a choice of two or more
alternatives... it should show the end of the selection with merge "---<>--" symbols.
. What is the purpose of a sentinel symbol if it is not acceptable value
It's value is that it can not be used as input to the algorithm and so it
can be used to signal the need to move on to something else.
. How does float differ from double
Floats don't use as many binary digits, are more approximate, and cover a smaller range of
real numbers.
. Examples of conversions
.See ./convert.cpp
. Explain implicit and explicit conversion
In C++ you can often convert data of one type to another type -- for example
converting an integer into a double. If you use a "cast" then it is explicit.
In an implicit conversion, you allow the compiler to choose a conversion from
one number type to another when necessary.
Notice that if you write
.As_is double answer = 1/2;
the division is int division and so `answer` is set to zero. However,
if one of the divisors was a double
.As_is double answer = 1/2.0;
then we get `answer` set to 0.5. Neither does "double(1/2)" work. The
division is done first (using int division) and then is converted to double.
:!
As a rule it is wise to use explicit conversions.
. How are cast operators used
These force numbers from one form to another: double to float to int to char.
The old fashioned notation was to use the target type. So to find the
character whose code is 32 we write:
.As_is char(32)
(in ASCII a space character). Similarly to get an accurate average from the sum of a number of int's we used to write:
.As_is average = double(sum)/number;
This still works but is `deprecated` (jargon for: "will not work forever").
The more modern and complex form is shown on line 81 of the listing
on page 158 of Deitel:
.As_is average = static_cast(sum)/number;
this should continue to compile and run correctly even if the standard
changes. And so this is the form you should use:-(
. How can I convert numbers to strings and strings to numbers
I've dug up a couple of advanced types of objects "stringstreams"
that do the job if you need it in a project, for example. Here
.See ./stringnumbers.cpp
is a program that demonstrates how to use
a couple of functions "convertDouble" and
"convertToDouble" that are defined in
.See ./stringnumbers.h
that you can download and #include in any of your programs.
Similar code can handle
other numeric data and let you choose the formatting.
. How do you output numbers to only 2 decimals
Use an IO Manipulator like this
.As_is cout << .... << setprecision(2) << ....;
.See ../examples/giomanip.cpp
.See ../examples/iomanip.cpp
This changes the format of doubles for the whole prgram.... until you change it to some other
precision.
. Avoiding infinite loops
The only way to avoid infinite loops is to think. You must be sure,
or better, must have proved that each time through the body, you
are closer to the terminating condition. For example, if you are
counting up, you condition should be `counter < some_limit`. If
you are going down then the condition will be `counter > some_value`.
Avoid using equality tests, by the way, in case the variable jumps over
the limit. This also stops you type `variable=limit` when you want
`variable==limit`.
The example in the book showed the need for braces {...} to include the
commands that change the controlled variable in the body of the loop.
It is important that you understand the syntax of loops and use braces
when needed. Indeed I tend to put them in in every loop, just in case.
But, there is no replacement for thought when coding loops and selections!
. Why can uninitialized variables lead to errors
Because 'int's and 'double's are not set up to be any particular value.
So if you are adding up data in an uninitialized variable the results
are unpredictable, and probably wrong.
. How do I make sure the user has given me one the small number of numbers I expect
This is a
.Key Data Validation
problem. Let us assume that the user must input either 1, 2, or 3. Also assume
that the user know enough to not input anything but an integer (not Roman "III", or
a real number "1.234". Then we need to
.(
Input a number
if the number is 1 it is valid
else if the number is 2 it is valid
else if the number is 3 it is valid
else it is invalid and the user should try again.
.)
This looks like a loop -- but how can we check the loop condition?
Here is a standard way to tackle it using the tools covered in the course so far.
.As_is int valid = 0; // 0 means invalid, 1 means valid
.As_is while(valid==0)
.As_is { cout << "Input either 1, 2, or 3: ";
.As_is cin >> number;
.As_is if (number==1)
.As_is valid=1;
.As_is else if (number==2)
.As_is valid=1;
.As_is else if (number==3)
.As_is valid=1;
.As_is
.As_is if(valid==0)
.As_is cout << number << " is invalid\n";
.As_is }
Using
.Key Boolean
Expressions and variables from Chapter 5 makes this much easier!
.Close
. Exercises
Selected from exercise 4.11 through to 4.35.
. Next -- How to design classes
.See ./10.html
. Lab -- experiments with control statements
.See ./lab05/