Professional Documents
Culture Documents
EDITION BROOKSHEAR
Chapter Five
ALGORITHMS
Chapter Summary
In this chapter we turn to an explicit study of algorithms—a topic that was introduced as the core of
computer science in Chapter 0. The chapter begins with a formal definition of an algorithm and a
discussion of the meaning of that definition. This leads to a discussion of algorithm creation (a creative
process that parallels the more generic task of problem solving) and algorithm representation (the
process of expressing an algorithm in preparation for, or during, programming). The chapter closes
with the subjects of algorithm efficiency (using big theta notation) and correctness.
The search for algorithm development techniques is presented as an ongoing activity—not a
settled issue. The chapter discusses some of the ideas proposed by researchers in the field of problem
solving and relates these ideas to the problem of algorithm discovery and representation.
This chapter also presents iterative structures by means of the sequential search and insertion sort
algorithms as well as recursive structures by means of the binary search algorithm. In each case,
emphasis is placed on the components involved in controlling the repetitive process.
For communication purposes, the chapter introduces a pseudocode that is closely aligned with
Python. This pseudocode is also used at times later in the text, although these later appearances are
rather intuitive in that they do not require previous, rigorous coverage of this chapter. So, if you’re
teaching a course for non-majors, you can treat the pseudocode lightly without creating problems in
future chapters.
25
Comments
1. You will find this text's approach to problem solving somewhat different from that of other texts.
The problem solving section in this chapter is intended to be a refreshingly honest discussion. It does
not try to convince students that they can become good problem solvers merely by learning a
particular problem solving technique. In particular, it does not preach top-down design via stepwise
refinement.
Students don't learn to solve problems by practicing explicit techniques in an isolated section of a
course. They learn to solve problems unconsciously over an extended period of time in which they
are required to do it. Thus, every chapter of the text is designed to develop the students' problem-
solving skills. (Maybe I'm old-fashioned, but I think we produce too much rhetoric about problem
solving and don’t require our students to do enough.)
3. The following is a problem that I have given students to work on. The point is not whether they
solve it but that they realize that solving a problem is a creative process that may not be achieved by
following a methodology. Actually, you could argue that there are many correct answers to this
problem, but I think you'll agree that the one given below is a good one.
Problem: Fill in the blank in the sequence
110, 20, 12, 11, 10, __, ...
Answer: 6. The pattern is
110 (base two) = 6, 20 (base three) = 6, 12 (base four) = 6
11 (base five) = 6, 10 (base six) = 6, so 6 (base seven) = 6
4. Here is a good problem for demonstrating bottom-up design and the use of abstraction in problem
solving. Imagine three railroad spurs each opening into a Y that connects to the other spurs. (It is
really three stacks, but we have not studied data structures yet.) Cars are on each spur and a
locomotive is in the “middle” of the track system. Show that the locomotive can rearrange the cars in
any order.
A first step is to show that the locomotive can move the car "on top" of any spur to the top of any
other spur. This is actually a two-step process since the locomotive must remain in the "middle" of
the track system. The next step is to show that any two cars on a spur can be interchanged. Then show
that any two cars in the system can be interchanged. Finally, show that any arrangement can be
obtained by a sequence of interchanging two cars at a time.
5. I've debated marking the introduction to recursion as an optional section, but the truth is that
recursion is a very important topic in computer science. I even include it when I teach "computer
literacy" to non-majors and have always found the class to respond well. (I show the class that solving
a problem recursively is like getting something for nothing—we always ask someone else to do the
hard work. The students like that.)
Thus, an important goal in this chapter is to begin developing the concept of recursion. I say "begin"
because experience has shown that students acquire an understanding of recursion over a period of
time. I like to devote a significant part of a class period to walking through an example of the binary
search, as done in the book. Each time another activation of the algorithm is called, I mark my place
in the current copy of the algorithm, move to a new location on the chalkboard, draw another copy,
copy the pertinent portion of the list next to it, and then proceed with execution. (Some form of
overhead projection saves time, but working on a chalkboard gives students time to think.) Each time
an activation terminates, I transfer its list back into the larger list in the previous activation, erase the
terminating activation, and then proceed in the previous one. Such a careful presentation pays
numerous dividends. Not only does it clearly present the recursive process, but it also sets the stage
for later discussions regarding stacking activation environments, issues of global versus local
variables, and parameter passing.
I also like to walk through some short examples such as
26
def PrintValues(Input):
if (Input != 0):
print(Input)
PrintValues(Input – 1)
in which I point out the difference in the output obtained by reversing the statements in the then
clause.
6. Here are some additional problems you may want to give your students. Each has the characteristic
that one can see a solution fairly quickly, but then one must wrestle with the problem of organizing
and expressing the solution.
a. Design an algorithm for solving the traveling salesman problem. (Given a network of roads, cities,
and mileages, find the shortest route that leads through each city at least once.)
b. Design an algorithm for converting a string of 1s into a string of 0s under the following constraints.
The right-most bit can always be complemented. Any other bit can be complemented if and only if
the bit to its immediate right is a 1 and all other bits to its right (if there are any) are 0.
c. Design an algorithm for testing a tic-tac-toe board to see if there has been a winner.
d. Design an algorithm for finding a path through a maze.
7. I like to use the problem "Design an algorithm for predicting the sum of the top and bottom faces
of four dice." to emphasize the distinction between algorithm discovery and algorithm representation.
In this case it’s the discovery step that may be tough. (Opposing faces on a die always add to seven.
Thus, the opposing faces on four dice must add to 28. Once this is discovered, the underlying
algorithm can be expressed as the single statement "print the value 28").
8. A good exercise for "experienced" programmers who think loop control is trivial is to design an
iterative algorithm for printing all possible permutations of a list of letters. (This is also a good
example of how the use of recursion can simplify matters.)
27
Count = 1
while (Count != 5):
print(Count)
Count = Count + 1
9. The conditions appearing in the statements would be negations of each other. That is, the statement
repeat (. . .) until (x is zero) is equivalent to do (. . .) while (x is not zero).
10. Here's an outline of one possible solution.
Starting from the right end of the input, find the first digit that is
smaller than the one to its right. (If there isn't such a digit, no the
input cannot be rearranged to represent a larger value.)
Call the position in the input in which this digit was found the target
position.
Interchange the digit found above with the smallest digit to its right
that is still larger than itself.
Sort the digits to the right of the target position in descending order
from right to left.
11. Suppose N is the given integer. Then the following will work. You may want to ask your students
how this solution could be made more efficient.
X = 1
while (X N):
if (X divides N):
print(X)
X = X + 1
12. Start with a date whose day of the week is known. Figure out how many days are between that
date and the given date (remember leap years). Then divide that total by seven and use the remainder
to determine the displacement from the known day.
13. Pseudocode is a relaxed version of a programming language used to jot down ideas. A formal
programming language prescribes strict rules of grammar that must be obeyed.
14. Syntax refers to the way something is expressed, whereas semantics refers to what is being
expressed.
15. W = 6, X = 9, Y = 5, Z = 1. Most will get their foot in the door by realizing that the carry has to be
1. Then they may figure out that X must be 9 since X + Y = 1Y.
16. V = 0, W = 4, X = 1, Y = 3, Z = 9. Most will get their foot in the door by realizing that X must be 1
since X times XY is XY. Then they may discover that Z must be 9 since it must be a one-digit perfect
square (Y times Y) which when added to one produces a carry.
17. X = 1, Y = 0. A simple algorithm would be to try X = 1 and Y = 0 first. If that works, report the
solution. Otherwise, try X = 0 and Y = 1. If that works, report the solution. Otherwise, report that there
is no solution.
18. Andrews and Blake go through the shaft first (2 minutes), and Andrews returns with the lantern
(1 minute). Then, Johnson and Kelly go through (8 minutes), and Blake returns with the lantern (2
minutes). Finally, Andrews and Blake go through again (2 minutes). The total travel time is 2 + 1 + 8
+ 2 + 2 = 15 minutes.
28
19. They are the same. Suppose the volume of the small glass is V and x units of water are poured into
the large glass. Then the large glass contains V + x units of liquid—V units of wine and x units of
water. When the small glass is filled from the large one, x units of liquid are returned to the small
glass of which V/(V + x) is wine. Therefore, the small glass will end up with xV/(V + x) units of wine.
Furthermore, xx/(V + x) units of water will be returned to the small glass, meaning that exactly x –
xx/(V + x) = xV/(V + x) units of water will be left in the large glass.
20. Approximately 122 meters. Let the distance between the hives be y. Since each bee flies at a
constant speed, the ratio of the distances traveled must be the same each time the meet. Therefore,
50/(y – 50) = (y + 20)/(2y – 20). Solving for y implies that y is approximately 7.5 meters or 122 meters.
21. How about this?
def SubStringSearch(FirstString, SecondString):
P = 0
Success = false
while (P + length of FirstString) <= (length of SecondString)
and Success == false):
N = 1
while (P + Nth character in SecondString ==
Nth character in FirstString):
N = N + 1
if (N == length of FirstString):
Success = true
P = P + 1
return Success
22. Body: Everything indented below the while
Initialization: The first two assignment statements
Modification: The last assignment statement (Some could argue that it is the last three
assignment statements.)
Test: while (Current < 100)
The output will be 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.
23. This is a recursive version of Problem 13. Its output will be 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.
24. Move the print statement below the recursive call to MysteryWrite.
25. When searching for J: H, L, J
When searching for Z: H, L, N, 0
26. Sequential search: 3000
Binary search: at least 13
27. a. Count 5 b. Count = 1 c. (Count 5) or (Total 56)
28. The body consists of the indented statements below the while. It will be executed twice. The
proposed modification would produce a nonterminating loop.
29. It may not terminate because the value in Count may never be exactly 1 (due to round-off errors).
30.
29
def Euclidean(X,Y):
if (neither X nor Y is 0):
if (X < Y):
Y = Y % X
else:
X = X % Y
return Euclidean(X,Y)
else:
if (X == 0):
return Y
else:
return X
31. Test1 would print 1, 2, 3, 4, whereas Test2 would print 4, 3, 2, 1.
32. The termination condition is Count = 5. The state of the process moves toward this condition
(assuming that Count starts with an integer value less than 5) each time a recursive call is made. (Note
that the procedures differ merely in that the recursive call and the print statement have been
interchanged.)
33. N 5
34. 3, 1, 0, 2, 4
35. 2, 0, 1, -1
36.
Trial = 2
repeat:
if (Trial % 2 is 0 or Trial % 3 is 0):
print(Trial)
Trial = Trial + 1
until (2 = 3)
37. a. binary b. sequential c. sequential d. binary
e. 5 for the sequential search; 1 for the binary search.
38.
def Factorial(Value):
if (Value == 0):
return 1
else:
return Value * Factorial(Value – 1)
39. a. Remove the first name from the list, leaving a list of only four names. Use the previous algorithm
to sort this shorter list. Then, insert the name removed earlier into this sorted list at its correct position.
b.
30
def Sort (List):
if (List has more than one name):
Remove the first name from List
Sort(List)
Insert the name removed earlier into List at its correct
position
40. This algorithm uses the following terminology: The peg on which the rings start is called the initial
peg, the peg to which the rings are to be moved is called the destination peg, the third peg is called
the auxiliary peg, and the number of rings to be moved is represented by N.
def Towers (Initial, Destination, Auxiliary, N):
if (N == 1):
Move the top ring from the Initial peg to the Destination peg
else:
Towers(Initial, Auxiliary, Destination, N-1)
Move the top ring from the Initial peg to the Destination peg
Towers(Auxiliary, Destination, Initial, N-1)
31
Guess = Number
repeat:
Guess = (Guess + (Number / Guess)) / 2
until (Guess * Guess is close enough to Number)
44.
def Permute (String):
if (String is only one character long):
return a list containing the String
else:
Remove first character from String
List = Permute(String)
PermList = new empty list
for each Entry in List:
for each possible position in Entry:
insert into Permlist Entry with the previously removed
character inserted at the possible position
return PermList
45.
if (list is not empty):
Longest = the first entry in the list
P = 2
while (P <= length of list):
if (the Pth entry in the list is longer than Longest)
Longest = the Pth entry
P = P + 1
If there is more than one longest entry, this algorithm reports the first one.
46.
Place the first five numbers in the set called Largest
Place the first five numbers in the set called Smallest
P = 6
while (P <= length of list):
if (the Pth entry in the list is larger than
the smallest entry in Largest):
replace the smallest entry in Largest with the Pth entry
if (the Pth entry in the list is smaller than
the largest entry in Smallest)
replace the largest entry in Smallest with the Pth entry
P = P + 1
47. Alphabetical order
48. 12 for the binary search, 4000 for the sequential search.
49. Allowing for carries, the addition of two n-digit values would require 2n – 1 additions. Thus,
addition would be in (n). To multiply two n-digit values requires n2 multiplications. Thus,
multiplication is in (n2).
50. To solve the first problem, sort the group by age, and form the subgroups by placing the youngest
person in one while putting all the rest in the other. The alternate problem requires the generation of
all possible divisions followed by the selection of the proper subgroup pair. Thus, the first problem is
a polynomial one, whereas the second is not.
32
51. 26 + 195 + 793 + 995 + 1156 = 3165. The best solution known for this problem is simply to try
different combinations in a systematic manner. If we're lucky we'll find the answer early. However,
with n numbers there are 2n - 1 different combinations, and thus exponential time might be required.
Indeed, this is a well-known NP problem called the knapsack problem.
52. Formally, the algorithm should never terminate because the value of X will never become 1.
However, when executed on a machine, it will terminate due to truncation errors.
53. No. The algorithm will not compute the correct answer when X = 0.
54. No. The algorithm will not compute the correct answer when X = Y.
55. No. The algorithm will not compute the correct answer if the list contains more than one entry and
the largest entry is the last.
56. a. Preconditions: The input list is arranged in ascending order.
Loop invariant: The target value is not equal to any list entry preceding the current entry.
b. Since the input list can contain only a finite number of entries and each time through the body
of the loop the current entry is advanced by one, at some point there will no longer remain entries to
be considered.
57. J is less than or equal to Y, and Z equals X - J.
33
Another random document with
no related content on Scribd:
Cerebral arteries, atheroma, v. 991
paralysis, v. 917
Cholera, i. 715
Chorea, v. 439
of the larynx, iii. 76
renal, iv. 42
Copodyscinesia, v. 504
Coryza, iii. 41
Cretinism, v. 138
D.
Degenerations, i. 72
Dementia, v. 164
Dengue, i. 879
Diphtheria, i. 656
Dreams, v. 368
Dyslalia, v. 571
E.
Eclampsia, v. 464
Ecstasy, v. 339
Effusions, i. 67
Elephantiasis, iv. 675
Epilepsy, v. 468
Epistaxis, iii. 50
Erythema, iv. 593, 595, 596
Erysipelas, i. 629
F.
Farcy, i. 909
G.
Glanders, i. 909