You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: ch13.tex
+59-69Lines changed: 59 additions & 69 deletions
Original file line number
Diff line number
Diff line change
@@ -4,8 +4,8 @@ \chapter{Objects of arrays}
4
4
5
5
In the previous chapter, we defined a class to represent cards and used an array of \java{Card} objects to represent a deck.
6
6
In this chapter, we take another step toward object-oriented programming by defining a class to represent a deck of cards.
7
-
We also present algorithms for shuffling and sorting decks.
8
-
Finally, we introduce \java{ArrayList} from the Java library and use it to keep track of which cards each player has from the deck.
7
+
We then present algorithms for shuffling and sorting decks.
8
+
Finally, we introduce \java{ArrayList} from the Java library and use it to keep track of different piles of cards from the deck.
9
9
10
10
%While reading the following sections, we recommend that you create a {\tt Deck.java} file and paste in all the examples.
11
11
%You will need {\tt Card.java} from the previous chapter for it to compile.
@@ -17,7 +17,7 @@ \chapter{Objects of arrays}
17
17
%Instructions for downloading this code are on page~\pageref{code}.
18
18
19
19
20
-
\section{The Deck class}
20
+
\section{Decks of cards}
21
21
\label{deck}
22
22
23
23
The first goal of this chapter is to create a \java{Deck} class that encapsulates an array of \java{Card}s.
@@ -78,7 +78,7 @@ \section{The Deck class}
78
78
79
79
Now that we have a \java{Deck} class, we have a logical place to put methods that pertain to decks.
80
80
Looking at the methods we have written so far, one obvious candidate is \java{printDeck} from Section~\ref{cardarray}.
81
-
Here's how it looks, rewritten as an instance method of \java{Deck}:
81
+
%Here's how it looks, rewritten as an instance method of \java{Deck}:
82
82
83
83
\begin{code}
84
84
public void print() {
@@ -96,7 +96,7 @@ \section{The Deck class}
96
96
%}
97
97
%\end{code}
98
98
99
-
Notice that when you transform a static method into an instance method, the code is shorter.
99
+
Notice that when we transform a static method into an instance method, the code is shorter.
100
100
We can simply type \java{deck.print()} to invoke this method.
101
101
102
102
@@ -118,8 +118,7 @@ \section{Shuffling decks}
118
118
\index{pseudocode}
119
119
120
120
A better shuffling algorithm is to traverse the deck one card at a time, and at each iteration, choose two cards and swap them.
121
-
Here is an outline of how this algorithm works.
122
-
To sketch the method, we will use a combination of Java statements and English.
121
+
To sketch an outline of how this algorithm works, we will use a combination of Java statements and English comments.
123
122
This technique is sometimes called {\bf pseudocode}.
124
123
125
124
\index{shuffle}
@@ -153,13 +152,13 @@ \section{Shuffling decks}
153
152
\index{swapCards}
154
153
155
154
Methods like \java{randomInt} and \java{swapCards} are called {\bf helper methods}, because they help you solve parts of the problem.
156
-
Helper methods are often \java{private}, since they are specific to the internal details of the class.
155
+
Helper methods are often \java{private}, since they are specific to the internal algorithms of the class.
157
156
158
157
\index{top-down design}
159
158
\index{design process}
160
159
161
160
This process of writing pseudocode first and then writing helper methods to make it work is called {\bf top-down design} (see \url{https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design}).
162
-
It is similar to ``incremental development'' and ``encapsulation and generalization'', the other design processes we have seen so far.
161
+
It is similar to ``incremental development'' and ``encapsulation and generalization'', the other design processes you have seen in this book.
163
162
164
163
One of the exercises at the end of the chapter asks you to write the helper methods \java{randomInt} and \java{swapCards}, and use them to implement \java{shuffle}.
165
164
@@ -197,7 +196,7 @@ \section{Selection sort}
197
196
\end{code}
198
197
199
198
200
-
One of the exercises at the end of the chapter asks you to write the helper method \java{indexLowest}; use it and \java{swapCards} to implement \java{selectionSort}.
199
+
One of the exercises at the end of the chapter asks you to write \java{indexLowest}, and then use it and \java{swapCards} to implement \java{selectionSort}.
201
200
202
201
203
202
\section{Merge sort}
@@ -213,15 +212,15 @@ \section{Merge sort}
213
212
\index{merge sort}
214
213
\index{sort!merge}
215
214
216
-
In the next two sections, we'll develop a more efficient algorithm called {\bf merge sort}.
215
+
We will develop a more efficient algorithm called {\bf merge sort}.
217
216
To sort $n$ items, merge sort takes time proportional to $n \log_2 n$.
218
217
That may not seem impressive, but as $n$ gets big, the difference between $n^2$ and $n \log_2 n$ can be enormous.
219
218
220
219
For example, $\log_2$ of one million is around 20.
221
220
So if you had to sort a million numbers, merge sort would require 20 million steps.
222
-
But selection sort would require one trillion!
221
+
But selection sort would require one trillion steps!
223
222
224
-
The idea behind merge sort is this: if you have two subdecks, each of which has already been sorted, it is easy and fast to merge them into a single, sorted deck.
223
+
The idea behind merge sort is this: if you have two subdecks, each of which has already been sorted, you can quickly merge them into a single, sorted deck.
225
224
Try this out with a deck of cards:
226
225
227
226
\begin{enumerate}
@@ -260,11 +259,11 @@ \section{Subdecks}
260
259
\end{code}
261
260
262
261
The first line creates an unpopulated subdeck (an array of \java{null} references).
263
-
Inside the \java{for} loop, the subdeck gets populated with references from the deck.
262
+
Inside the \java{for} loop, the subdeck gets populated with references in the deck.
264
263
265
264
\index{off-by-one}
266
265
267
-
The length of the subdeck is \java{high - low + 1}, because both the low card and the high card are both included.
266
+
The length of the subdeck is \java{high - low + 1}, because both the low card and the high card are included.
268
267
This sort of computation can be confusing, and forgetting the ``\java{+ 1}'' often leads to {\bf off-by-one} errors.
269
268
Drawing a picture is usually the best way to avoid them.
270
269
@@ -371,7 +370,7 @@ \section{Adding recursion}
371
370
\index{leap of faith}
372
371
373
372
As usual, there are two ways to think about recursive programs: you can think through the entire flow of execution, or you can make the ``leap of faith'' (see Section~\ref{leap_of_faith}).
374
-
This example might encourage you to make the leap of faith.
373
+
This example should encourage you to make the leap of faith.
375
374
376
375
When you used \java{selectionSort} to sort the subdecks, you didn't feel compelled to follow the flow of execution.
377
376
You just assumed it works because you had already debugged it.
@@ -381,11 +380,12 @@ \section{Adding recursion}
381
380
Well, almost.
382
381
You might have to give some thought to getting the base case right and making sure that you reach it eventually.
383
382
But other than that, writing the recursive version should be no problem.
383
+
The most difficult part of merge sort is the \java{merge} method, and that part is not recursive.
384
384
385
385
386
386
\section{Static context}
387
387
388
-
Figure~\ref{fig.deck} lists the methods we have discussed.
388
+
Figure~\ref{fig.deck} lists the \java{Deck} methods we have so far.
389
389
In UML diagrams, \java{private} methods begin with a minus sign (\java{-}), and \java{static} methods are underlined.
390
390
391
391
\begin{figure}[!ht]
@@ -397,18 +397,21 @@ \section{Static context}
397
397
\end{figure}
398
398
399
399
The helper methods \java{randomInt} and \java{merge} are \java{static}, because they do not require \java{this.cards}.
400
-
All other methods are instance methods, because they require a specific instance of \java{this.cards}.
400
+
All other methods are instance methods, because they require an instance of \java{this.cards}.
401
401
For example, you cannot invoke the \java{print} method this way:
402
402
403
403
\begin{code}
404
404
Deck.print(); // wrong!
405
405
\end{code}
406
406
407
+
% DW suggested that at some point we should warn students
408
+
% about using \java{this} in a static method
409
+
407
410
\index{static context}
408
411
\index{this}
409
412
410
413
If you try to compile this code, you will get the error, ``non-static method print() cannot be referenced from a static context.''
411
-
By {\bf static context}, the compiler means you are trying to invoke a method without \java{this}.
414
+
By {\bf static context}, the compiler means you are trying to invoke a method without passing \java{this}.
412
415
To invoke an instance method, you need an instance:
413
416
414
417
\begin{code}
@@ -418,22 +421,21 @@ \section{Static context}
418
421
419
422
Notice that \java{Deck} with a capital \java{D} is a class, and \java{deck} with a lowercase \java{d} is a variable.
420
423
When you invoke \java{deck.print()}, the reference of \java{deck} becomes the reference \java{this}.
421
-
Static methods cannot refer to \java{this}, because they are not bound to a specific object.
424
+
425
+
In static methods, there is no such thing as \java{this}.
426
+
If you refer to \java{this} in a static method, you will get the compiler error, ``non-static variable this cannot be referenced from a static context.''
422
427
423
428
\begin{code}
424
429
private static Deck merge(Deck d1, Deck d2) {
425
430
return this.cards; // wrong!
426
431
}
427
432
\end{code}
428
433
429
-
If you refer to \java{this} in a static method, you will get the compiler error, ``non-static variable this cannot be referenced from a static context.''
430
-
In static methods, there is no such thing as \java{this}.
431
-
432
434
\index{sort!Arrays}
433
435
\index{array!sorting}
434
436
435
-
Normally, we wouldn't implement three different sorting algorithms in the same class.
436
-
Our goal with \java{Deck} was to demonstrate different ways of solving the same problem.
437
+
Normally we wouldn't implement three different sorting algorithms in the same class.
438
+
Our goal with \java{Deck} was to demonstrate static methods and different ways of solving the same problem.
437
439
In practice, we could just write a single \java{sort} method that uses \java{java.util.Arrays}.
438
440
439
441
\begin{code}
@@ -450,12 +452,13 @@ \section{Static context}
450
452
\section{Piles of cards}
451
453
452
454
Now that we have a working \java{Deck} class, let's use it to implement a simple card game.
453
-
One of the simplest games that children often play is ``War'' (see \url{https://en.wikipedia.org/wiki/War_(card_game)}).
455
+
One of the simplest card games that children play is called``War'' (see \url{https://en.wikipedia.org/wiki/War_(card_game)}).
454
456
455
457
In this game, the deck is divided into two or more piles.
456
458
Players take turns revealing the top card of their pile.
457
-
If there is a tie, players set aside three more cards and reveal their next card.
458
-
Whoever has the highest ranking card takes all the cards that were played.
459
+
Whoever has the highest ranking card takes the two cards.
460
+
If there is a tie, players draw four more cards.
461
+
Whoever has the highest ranking fourth card takes all ten cards.
459
462
The game continues until one player has won the entire deck.
460
463
461
464
We could use the \java{Deck} class to represent the individual piles.
@@ -505,7 +508,7 @@ \section{Piles of cards}
505
508
506
509
\index{this}
507
510
508
-
We also need to be able to remove cards from ``the top'' of the pile.
511
+
We also need to be able to remove cards from the top (or front) of the pile.
509
512
If we use \java{ArrayList.remove}, it will automatically shift the remaining cards left to fill the gap.
510
513
511
514
\begin{code}
@@ -525,7 +528,7 @@ \section{Piles of cards}
525
528
\index{wrapper method}
526
529
527
530
Methods like \java{addCard}, \java{popCard}, and \java{size}, which invoke another method without doing much additional work, are called {\bf wrapper methods}.
528
-
The last method we need adds an entire subdeck at the beginning of the game.
531
+
The last method we need adds an entire subdeck to the pile.
529
532
530
533
\begin{code}
531
534
public void addDeck(Deck deck) {
@@ -536,7 +539,7 @@ \section{Piles of cards}
536
539
\end{code}
537
540
538
541
Now we can use \java{Deck} and \java{Pile} to implement the game.
539
-
In \java{War.java}, the\java{main} method begins like this:
542
+
The\java{main} method begins like this:
540
543
541
544
\begin{code}
542
545
// create and shuffle the deck
@@ -567,7 +570,7 @@ \section{Piles of cards}
567
570
} else if (diff < 0) {
568
571
p2.addCard(c1);
569
572
p2.addCard(c2);
570
-
} else { // it's a tie...draw three more cards
573
+
} else { // it's a tie...draw four more cards
571
574
\end{code}
572
575
573
576
One of the exercises at the end of this chapter asks you to implement the \java{else} block when there's a tie.
@@ -605,16 +608,13 @@ \section{Vocabulary}
605
608
A recursive sorting algorithm that divides an array into two parts, sorts each part (using merge sort), and merges the results.
606
609
607
610
\term{off-by-one}
608
-
A common programming mistake that results in iterating one too few (or too many) times.
609
-
610
-
%\term{insertion sort}
611
-
%Another sorting algorithm that inserts elements into place, one at a time.
611
+
A common programming mistake that results in iterating one too few times (or one too many).
612
612
613
613
\term{static context}
614
614
The parts of a class that run without reference to a specific instance of the class.
615
615
616
616
\term{collection}
617
-
An object that contains other objects, or more specifically, one of the objects in the Java library, like \java{ArrayList}, that contains objects.
617
+
A Java library class (such as \java{ArrayList}) that represents a group of objects.
618
618
619
619
\term{wrapper method}
620
620
A method that calls another method without doing much additional work.
@@ -651,18 +651,17 @@ \section{Exercises}
651
651
652
652
\begin{enumerate}
653
653
654
-
\item In the repository for this book, you should find a file called {\tt Deck.java} that contains the code in this chapter.
654
+
\item In the repository for this book, you should find the file named {\tt Deck.java}.
655
655
Check that you can compile it in your environment.
656
656
657
-
\item Add a \java{Deck} method called \java{randomInt} that takes two integers, \java{low} and \java{high}, and returns a random integer between \java{low} and \java{high}, including both.
658
-
You can use the \java{nextInt} provided by \java{java.util.Random}, which we saw in Section~\ref{random}.
659
-
660
-
{\it Hint:} You can avoid creating a \java{Random} object every time \java{randomInt} is invoked by defining and using a class variable.
657
+
\item Implement the \java{randomInt} method.
658
+
You can use the \java{nextInt} method provided by \java{java.util.Random}, which we saw in Section~\ref{random}.
661
659
660
+
{\it Hint:} Avoid creating a \java{Random} object every time \java{randomInt} is invoked by defining a class variable.
662
661
663
-
\itemWrite a method called \java{swapCards} that takes two indexes and swaps the cards at the given locations.
662
+
\itemImplement the \java{swapCards} method that takes two indexes and swaps the cards at the given locations.
664
663
665
-
\itemWrite a method called \java{shuffle} that uses the algorithm in Section~\ref{shuffle}.
664
+
\itemImplement the \java{shuffle} method using the algorithm in Section~\ref{shuffle}.
666
665
667
666
\end{enumerate}
668
667
@@ -672,23 +671,25 @@ \section{Exercises}
672
671
\begin{exercise} %%V6 Ex13.3
673
672
674
673
The goal of this exercise is to implement the sorting algorithms from this chapter.
675
-
Use the {\tt Deck.java} file from the previous exercise (or create a new one from scratch).
674
+
Use the {\tt Deck.java} file from the previous exercise, or create a new one from scratch.
676
675
677
676
\begin{enumerate}
678
677
679
-
\item Write a method called \java{indexLowest} that uses the \java{compareCard} method to find the lowest card in a given range of the deck (from \java{lowIndex} to \java{highIndex}, including both).
678
+
\item Implement the \java{indexLowest} method.
679
+
Use the \java{Card.compareTo} method to find the lowest card in a given range of the deck (from \java{lowIndex} to \java{highIndex}, including both).
680
680
681
-
\itemWrite a method called \java{selectionSort} that implements the selection sort algorithm in Section~\ref{sorting}.
681
+
\itemImplement \java{selectionSort} using the algorithm in Section~\ref{sorting}.
682
682
683
-
\item Using the pseudocode in Section~\ref{mergesort}, write the method called \java{merge}.
683
+
\item Using the pseudocode in Section~\ref{mergesort}, implement the \java{merge} method.
684
684
The best way to test it is to build and shuffle a deck.
685
685
Then use \java{subdeck} to form two small subdecks, and use selection sort to sort them.
686
-
Then you can pass the two halves to \java{merge} to see if it works.
686
+
Finally, pass the two halves to \java{merge} and see if it works.
687
687
\index{testing}
688
688
689
-
\item Write the simple version of \java{mergeSort}, the one that divides the deck in half, uses \java{selectionSort} to sort the two halves, and uses \java{merge} to create a new, sorted deck.
689
+
\item Implement \java{almostMergeSort}, the one that divides the deck in half, uses \java{selectionSort} to sort the two halves, and uses \java{merge} to create a new, sorted deck.
690
+
You should be able to reuse code from the previous step.
690
691
691
-
\itemWrite a recursive version of \java{mergeSort}.
692
+
\itemImplement \java{mergeSort} recursively.
692
693
Remember that \java{selectionSort} is a modifier and \java{mergeSort} is a pure method, which means that they get invoked differently:
693
694
694
695
\begin{code}
@@ -701,36 +702,25 @@ \section{Exercises}
701
702
\end{exercise}
702
703
703
704
704
-
\begin{exercise} %%V6 Ex13.4
705
-
706
-
The goal of this exercise is to practice top-down design.
707
-
First read about ``insertion sort'' at \url{http://www.sorting-algorithms.com/insertion-sort}.
708
-
Then write a method named \java{insertionSort} that implements this algorithm.
709
-
Your method should use at least one helper method.
710
-
711
-
\end{exercise}
712
-
713
-
714
705
\begin{exercise} %%V6.5 NEW
715
706
716
-
Open the file \java{War.java} in the repository.
707
+
Find and open the file \java{War.java} in the repository.
717
708
The \java{main} method contains all the code from the last section of this chapter.
718
709
Check that you can compile and run this code before proceeding.
719
710
720
711
The program is incomplete; it does not handle the case when two cards have the same rank.
721
-
Finish implementing the \java{main} method beginning at the line that says: \java{// it's a tie...draw three more cards}.
712
+
Finish implementing the \java{main} method beginning at the line that says: \java{// it's a tie...draw four more cards}.
722
713
723
-
When there's a tie, you need to draw three cards from each pile and store them in another collection.
714
+
When there's a tie, draw three cards from each pile and store them in a collection, along with the original two.
724
715
Then draw one more card from each pile and compare them.
725
-
Whoever wins the tie will take all eight of these cards.
716
+
Whoever wins the tie will take all ten of these cards.
726
717
727
718
If one pile does not have at least four cards, the game ends immediately.
728
719
If a tie ends with a tie, flip a coin and give the cards to one of the players.
729
720
730
-
Notice that the program depends on \java{Deck.shuffle}.
731
-
If you haven't implemented the \java{shuffle} method (see Exercise~\ref{ex.shuffle}), every play will be a tie.
732
-
Player 1 will have the Ace through King of the first two suits, and Player 2 will have the the Ace through King of the remaining two suits, all in the same order.
733
-
As a result, the winner will be random.
721
+
Notice that this program depends on \java{Deck.shuffle}.
722
+
If you haven't implemented the \java{shuffle} method (see Exercise~\ref{ex.shuffle}), the game won't be that fun.
723
+
Player 1 will have the Ace through King of the first two suits, and Player 2 will have the the Ace through King of the other two suits, all in the same order.
0 commit comments