stanford handout
TRANSCRIPT
-
7/30/2019 stanford handout
1/221
Handout #17 Spring 2002April 15, 2002 Robert Plummer
Section Handout 2Written by Nicholas Fang, with thanks to Jerry Cain, Bob Plummer, Eric Roberts, and the TAs that have come before.
Problem 1: Bracket Matching
In the syntax of most programming languages, there are some characters that occur only innested pairs, which are called bracketing operators. ANSI C, for example, defines the following
bracketing operators:
( ... )
[ ... ]
{ ... }
In a properly formed program, these characters will be properly nested and matched. To
determine whether this condition holds for a particular program, you can ignore all the othercharacters and look simply at the pattern formed by the parentheses, brackets, and braces. In alegal configuration, all the operators match up correctly, as shown in the following example:
{ ( [ ] ) ( [ ( ) ] ) }
The following configurations, however, are illegal for the reasons stated:
( ( [ ] ) The line is missing a close parenthesis.
) ( The close parenthesis comes before the open parenthesis.{ ( } ) The parentheses and braces are improperly nested.
For this problem, your task is to write a recursive function
bool IsBalanced(string str)
that takes a string str from which all characters except the bracketing operators have been
removed. The function should return TRUE if the bracketing operators in str are balanced, which
means that they are correctly nested and aligned. If the string is not balanced, IsBalancedshould return FALSE.
Although there are many other ways to implement this operation, you should code your solutionso that it embodies the recursive insight that a string consisting only of bracketing characters is
balanced if and only if one of the following conditions holds:
1. The string is empty.
2. The string contains "()", "[]", or "{}" as a substring and is balanced if you remove that
substring.
CS106B
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
2/221
2
Forexample,thestring"[(){}]"isshowntobebalancedbythefollowingchainofcalls:
IsBalanced("[(){}]")
IsBalanced("[{}]")
IsBalanced("[]")
IsBalanced("") TRUE
Your implementation of IsBalancedmust operate recursively and may include no explicit for
or while statements.
Problem 2: Arithmetic Combinations
Write a function ArithmeticCombinations which given an array of integers and a desired
result, recursively determines how many different ways you can combine those integers to formthat result. Combining the numbers means choosing a sequence of arithmetic operations to apply
to the numbers to produce an expression that evaluates to result. The sum starts as zero and you
process the numbers in the array from left to right. For each number, you can either add it to thecurrent sum, subtract it from the current sum or multiply the current sum by the number. All
numbers in the array must be used in the expression. For example, consider the array (5 2 3
6) and desired result 15. There are two possible arithmetic combinations:
5 + 2 * 3 - 6 = 15
5 - 2 * 3 + 6 = 15
Note the expression is not evaluated using C precedence rules, it is simply evaluated left to right.
The first two parameters are the array of numbers and its effective size (you can assume the arraycontains at least one number). The third parameter is the desired result. Your function should
return the count of the different ways you can combine the numbers to get that result (you do nothave to keep track of the combinations, just report the number of possible combinations). Youwill need to write a helper function. Use the following prototype:
int ArithmeticCombinations(int arr[], int n, int desiredResult)
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
3/221
3
Problem 3: Finding a Path
Consider the following map, which shows six cities, labeled 0 through 5, and the roads thatconnect them.
The roads are all two-way, meaning that you can go from 0 to 1 and also from 1 to 0.
This problem is concerned with finding pathways between cities. For example, if you want to
know how to get from 0 to 5, you can look at the map and see that the way to do it is to go from0 to 3 to 2 to 5. In this map you can get from any city to any other city, but not all maps are like
that. For example, if a flood washed out the road from 0 to 3, then there would be no path from 0to 5.
Your job in this problem is to write a function that finds paths between cities in maps like thisone (or determines that no path exists). The first thing to think about, of course, is how the mapwill be represented. We will do that using a "connection matrix", which is just a two-dimensional
array ofbools such that the element at position [i][j] is TRUE if there is a road between citiesi
and j, and FALSE if there isn't. Here is the matrix for the map shown above. The city numbers
outside the box aren't part of the matrix; they are just there to help you relate the matrix to the
map above. Also, weve just used T and F for TRUE and FALSE:
0 1 2 3 4 5
0 F T F T F F
1 T F F F T F
2 F F F T F T
3 T F T F F F
4 F T F F F F
5 F F T F F F
The fact that the roads are two-way means that the matrix is symmetric. That is, if element [i][j] is TRUE then element [j][i] is TRUE also. Just as a final check that you are with us on
this, the fact that there is a road between cities 3 and 2 means that (using connect as the name of
the array) both connect[3][2] and connect[2][3] are TRUE. Notice also that we have placed
the value FALSE on the main diagonal. This will prove to be convenient, and you can assume that
we will never ask our path finding function whether you can reach a city from itself.
4
1
25
3
0
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
4/221
4
Searching for paths between two specified cities can involve a lot of work, especially if the
matrix is large. You might go quite a way down a certain path, only to find that it is a dead endas far as getting to your intended destination is concerned. In the map above, for example, if you
were trying to find a path from 0 to 5, you might try going from 0 to 1 and then to 4. That doesn't
get you there, so you will have to back up and try some more paths before finding what you arelooking for or concluding that the path doesn't exist.
Does this sound a bit familiar? That's right: one way to look for paths is with a recursive
backtracking procedure, and that's what we want you to do. Your job is to write a recursiveprocedure PathExists with the following prototype (assume thatNUM_CITIES is a #defined
constant that gives the number of cities in the connection array):
bool PathExists(int from, int to, bool connect[][NUM_CITIES]);
Your function should return TRUE is a path exists between cities fromand to, and FALSE if there
is no path. Note that we haven't passed in the number of cities; you can just use the constant
NUM_CITIES in your function as needed.
Problem 4: Recursion and Big-O
Assume that the function F and its helper function G have been defined as follows:
int F(int n)
{
return G(n * n * n, n * n, n);
}
int G(int n1, int n2, int n3){
if (n1 != 0) return 1 + G(n1 - 1, n2, n3);
else if (n2 != 0) return 1 + G(n1, n2 - 1, n3);
else if (n3 != 0) return 1 + G(n1, n2, n3 - 1);
else return 0;
}
What is the value ofF(3)? What is the computational complexity of the F function expressed in
terms ofN, whereN is the value of the argument to F?
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
5/221
Handout #17S Spring 2002April 15, 2002 Robert Plummer
Section Solutions 2Thanks again to Jerry Cain, Bob Plummer, and Eric Roberts!
Problem 1: Bracket Matching
/** Function: IsBalanced
* Usage: if (IsBalanced(line)) { ...
* ----------------------------------
* This function determines if the given string, which is just
* a series of open and close brackets with all other characters
* removed, represents a properly balanced set of brackets.
* This is done by working from inside out. If the string is empty,
* then it is balanced by default. Otherwise, look for a consecutive
* matched pair of brackets (either (), [], or {}). If one isnt
* found, then this isnt a balanced string. Otherwise, remove the
* pair and check the rest of the string to see if it is balanced.
*/
bool IsBalanced(string str)
{
string head, tail;
int cp;
if (StringEqual(str, "")) return (TRUE);
cp = FindString("()", str, 0);
if (cp == -1) cp = FindString("[]", str, 0);
if (cp == -1) cp = FindString("{}", str, 0);
if (cp == -1) return (FALSE);
head = SubString(str, 0, cp - 1);
tail = SubString(str, cp + 2, StringLength(str) - 1);
return (IsBalanced(Concat(head, tail)));
}
CS106B
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
6/221
2
Problem 2: Arithmetic Combinations
/*
* Function: ArithmeticCombinations
* Usage: ArithmeticCombinations(values, numValues, target);
* ---------------------------------------------------------
* A wrapper function for Combos, which figures out if it is possible
* to combine the given values arithmetically in order to hit the
* desired target value.
*/
int ArithmeticCombinations(int array[], int n, int desiredResult)
{
return Combos(array, n, desiredResult, 1, array[0]);
}
/*
* Function: Combos
* Usage: Combos(array, n, desiredResult, 1, array[0]);
* ----------------------------------------------------
* Recursively determines whether the values in the given array can be
* combined using addition, subtraction, and multiplication to reach the* given target number. Each call is responsible for handling one number,
* with the current number being kept track of by pos. The total number
* of ways to reach the target is a combination of the ways to reach it
* where the current target is added, subtracted, or multiplied to the
* current value. When all numbers are done, if the total matches
* the desired, then one way has been found.
*/
int Combos(int array[], int n, int desired, int pos, int total)
{
if (pos == n) return (total == desired ? 1 : 0);
return (Combos(array, n, desired, pos + 1, total + array[pos]) +
Combos(array, n, desired, pos + 1, total array[pos]) +
Combos(array, n, desired, pos + 1, total * array[pos]));
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
7/221
3
Problem 3: Finding a Path
/*
* Function: PathExists
* Usage: if (PathExists(from, to, connect)) { ...
* -----------------------------------------------
* This is a wrapper function for Path, which determines if there is
* a path between two given cities in a map. Sets up a list to keep track
* of which locations have been visited and clears this list, then calls* Path to actually do the work.
*/
bool PathExists(int from, int to, bool connect[][NUM_CITIES])
{
int i;
bool visited[NUM_CITIES];
for (i = 0; i < NUM_CITIES; i++)
visited[i] = FALSE;
return (Path(from, to, connect, visited));
}
/*
* Function: Path
* Usage: return (Path(from, to, connect, visited));
* -------------------------------------------------
* Recursively attempts to find a path from the from city to the to
* city, where the connections between cities are specified by the
* connection graph stored in connect. Does a standard recursive
* backtracking algorithm, marking visited cities in the visited array
* to prevent infinite loops.
*/
bool Path(int from, int to, bool connect[][NUM_CITIES], bool visited[])
{
int i;
if (visited[from]) return FALSE;
if (from == to) return TRUE;
/* note: if (connect[from][to]) is also correct here */
visited[from] = TRUE;
for (i = 0; i < NUM_CITIES; i++) {
if (connect[from][i] && Path(i, to, connect, visited))
return TRUE;
}
visited[from] = FALSE;
return FALSE;
}
Problem 4: Recursion and Big-O
F(n) = n3 + n2 + n; so F(3) = 27 + 9 + 3 =39.
Complexity: F(n) is O (N3 + N2 + N), which isO(N3).
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
8/221
Eric Roberts Handout #17
CS106B January 23, 2012
Section Handout #2ADTs
Problem 1. Using grids (Chapter 5, exercise 10, page 253)In the game of Minesweeper, a player searches for hidden mines on a rectangular grid
that mightfor a very small boardlook like this:
One way to represent that grid in C++ is to use a grid of Boolean values marking minelocations, where trueindicates the location of a mine. In Boolean form, this sample gridtherefore looks like this:
Given such a grid of mine locations, write a function
void fixCounts(Grid & mines, Grid & counts);
that creates a grid of integers storing the number of mines in each neighborhood. Theneighborhood of a location includes the location itself and the eight adjacent locations,
but only if they are inside the boundaries of the grid. The reference parametercountsisused to store the result. Your job in this exercise is to make sure that it has the same size
as theminesgrid and then to assign to each element an integer between 0 and 9. For
example, ifmineLocationscontains the Boolean grid shown earlier, the code
Grid mineCounts;
fixCounts(mineLocations, mineCounts);
should initializemineCountsas follows:
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
9/221
2
Problem 2. Using queues (Chapter 5, exercise 13, page 255)
Bob Dylans 1963 song The Times They Are A-Changin contains the following lines,which are themselves paraphrased from Matthew 19:30:
And the first one now
Will later be last
For the times they are a-changin
In keeping with this revolutionary sentiment, write a function
void reverseQueue(Queue & queue);
that reverses the elements in the queue. Remember that you have no access to theinternal representation of the queue and will need to come up with an algorithm,
presumably involving other data structures, to accomplish the task.
Problem 3. Using maps (Chapter 5, exercise 21, page 259)
In May of 1844, Samuel F. B. Morse sent the message What hath God wrought! bytelegraph from Washington to Baltimore, heralding the beginning of the age of electronic
communication. To make it possible to communicate information using only the
presence or absence of a single tone, Morse designed a coding system in which lettersand other symbols are represented as coded sequences of short and long tones,
traditionally called dots and dashes. In Morse code, the 26 letters of the alphabet arerepresented by the following codes:
A J S
B K T
C L U
D M V
E N W
F O X
G P Y H Q Z
I R
Write a program that reads in lines from the user and translates each line either to or from
Morse code depending on the first character of the line:
If the line starts with a letter, you want to translate it to Morse code. Any characters
other than the 26 letters should simply be ignored.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
10/221
3
If the line starts with a period (dot) or a hyphen (dash), it should be read as a series of
Morse code characters that you need to translate back to letters. Each sequence ofdots and dashes is separated by spaces, but any other characters should be ignored.
The program should end when the user enters a blank line. A sample run of this program
(taken from the messages between the Titanic and the Carpathia in 1912) might look likethis (note that there are no spaces in the Morse-to-letters translation):
Although it is easy to use a switch statement to convert from letters to Morse code,
converting in the opposite direction requires a map. Given that you need to initialize a
map for at least one of the directions, you should try to find a strategy that allows you touse the data in that map for both the letters-to-Morse and the Morse-to-letters translation.
Problem 4. Using lexicons (Chapter 5, exercise 22, page 260)
Section 3.6 defines the function isPalindrome that checks whether a word readsidentically forward and backward. Use that function together with the English lexicon to
print out a list of all words that are palindromes.
MorseCode
Morse code translator
> SOS TITANIC
... --- ... - .. - .- -. .. -.-.
> WE ARE SINKING FAST
.-- . .- .-. . ... .. -. -.- .. -. --. ..-. .- ... -
> .... . .- -.. .. -. --. ..-. --- .-. -.-- --- ..-
HEADINGFORYOU
>
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
11/221
Eric Roberts Handout #17A
CS106B January 23, 2012
Solutions to Section Handout #2
Problem 1. Using grids
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
12/221
2
Problem 2. Using queues
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
13/221
3
Problem 3. Using maps
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
14/221
4
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
15/221
5
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
16/221
6
Problem 4. Using lexicons
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
17/221
CS106B Handout #11Spring 03-04 April 12, 04
Section Handout #2
Problem 1: CannonballsSuppose that you have somehow been transported back to 1777 and the Revolutionary War. Youhavebeenassignedadangerousreconnaissancemission:evaluatetheamountofammunitionavailable to the British for use with their large cannon which has been shelling the Revolutionaryforces. Fortunately for you, the Britishbeing neat and orderlyhave stacked the cannonballsinto a single pyramid-shaped stack with one cannonball at the top, sitting on top of a squarecomposed of four cannonballs, sitting on top of a square composed of nine cannonballs, and soforth. Unfortunately, however, the Redcoats are also vigilant, and you only have time to countthenumberoflayersinthepyramidbeforeyouareabletoescapebacktoyourowntroops. Tomake matters worse, computers will not be invented for at least 150 years, but you should not letthat detail get in your way. Your mission is to write a recursive function Cannonball that takes
as its argument the height of the pyramid and returns the number of cannonballs therein.
static int Cannonball(int height);
Problem 2: ReverseStringGivenastring,createafunctionReverseStringthatreturnsthestringinreverseorder.Considerboth recursive and iterative techniques for solving this problem. Which one is easier to come upwith?
staticstringReverseString(stringstr);
Problem 3: GCD
The greatest common divisor (g.c.d.) of two nonnegative integers is the largest integer thatdivides evenly into both. In the third century B.C., the Greek mathematician Euclid discoveredthat the greatest common divisor of x and y can always be computed as follows:
Ifx is evenly divisiblebyy, theny is thegreatest commondivisor. Otherwise, thegreatest common divisor of x and y is always equal to the greatest common divisor of yand the remainder ofx divided by y.
Use Euclid's insight to write a recursive function static int GCD(int x, int y) that computesthe greatest common divisor of x and y.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
18/221
2
Problem 4: Old-Fashioned Measuring (Chapter 5, Programming Exercise 10)
Iamtheonlychildofparentswhoweighed,measured,andpricedeverything;forwhomwhatcouldnotbeweighed,measured,andpriced had no existence.
Charles Dickens,Little Dorrit, 1857
In Dickenss time, merchants measured many commodities using weights and a two-pan balanceapracticethatcontinuesinmanypartsoftheworldtoday.Ifyouareusingalimitedsetofweights, however, you can only measure certain quantities accurately.
For example, suppose that you have only two weights: a 1-ounce weight and a 3-ounce weight.With these you can easily measure out 4 ounces, as shown:
31
It is somewhat more interesting to discover that you can also measure out 2 ounces by shiftingthe 1-ounce weight to the other side, as follows:
31
Write a recursive function
bool IsMeasurable(int target, int weights[], int nWeights)
that determines whether it is possible to measure out the desired target amount with a given setof weights. The available weights are stored in the array weights, which has nWeightsas its
effective size. For instance, the sample set of two weights illustrated above could be representedusing the following pair of variables:
int sampleWeights[] = { 1, 3 };
int nSampleWeights = 2;
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
19/221
3
Given these values, the function call
IsMeasurable(2, sampleWeights, nSampleWeights)
should returntruebecause it is possible to measure out 2 ounces using the sample weight set as
illustrated in the preceding diagram. On the other hand, calling
IsMeasurable(5, sampleWeights, nSampleWeights)
should return false because it is impossible to use the 1- and 3-ounce weights to add up to 5ounces.
Thefundamentalobservationyouneedtomakeforthisproblemisthateachweightinthearraycan be either:3. Put on the opposite side of the balance from the sample4. Put on the same side of the balance as the sample5. Left offthe balance entirely
Ifyouconsideroneoftheweightsinthearrayanddeterminehowchoosingoneofthesethreeoptions affects the rest of the problem, you should be able to come up with the recursive insightyou need to solve the problem.
Problem 5: List Mnemonics
On the standard Touch-Tone telephone dial, the digits are mapped onto the alphabet (minusthe letters Q andZ) as shown in the diagram below:
PICT-05-30
1 2 3
4 5 6
7 8 9
0* #
ABC DEF
GHI JKL MNO
PRS TUV WXY
In order to make their phone numbers more memorable, service providers like to find numbers
that spell out some word (called a mnemonic) appropriate to their business that makes thatphone number easier to remember. For example, the phone number for a recorded time-of-daymessage in some localities is 637-8687 (NERVOUS).
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
20/221
4
Imagine that you have just been hired by a local telephone company to write a functionListMnemonics that will generate all possible letter combinations that correspond to a givennumber, represented as a string of digits. For example, if you call
ListMnemonics("723")
your program should generate the following 27 possible letter combinations that correspond tothat prefix:
PAD PBD PCD RAD RBD RCD SAD SBD SCD
PAE PBE PCE RAE RBE RCE SAE SBE SCE
PAF PBF PCF RAF RBF RCF SAF SBF SCF
Problem 6: Spot the BugWhiledebuggingsomecode,younarrowyoursearchdowntothefollowingDoubleArrayLengthfunction. Unfortunately, because pointers and arrays are rather difficult to display in a debugger,yourehavingsometroublefindingthebug.Youdecideinsteadtotracethefunctionbyhandtosee if you can spot the bug. Trace through a call to the following function to find the bug. Onceyou have found the bug, determine what should be done to fix it.
/* The following function doubles the length of an array of integers */
static void DoubleArrayLength(int *array, int length)
{
int *newArray = new int[length * 2];
for (int i = 0; i < length; i++)
{
newArray[i] = array[i];
}
for (int i = length; i < length * 2; i++)
{
newArray[i] = 0;
}
array = newArray;
}
int main()
{
int *myArray = new int[5];
for (int i = 0; i < 5; i++)
{
myArray[i] = i;
}
DoubleArrayLength(myArray, 5);
cout
-
7/30/2019 stanford handout
21/221
CS106B Handout #11SSpring 03-04 April 12, 04
Section Solutions #2
Problem 1: Cannonballs/*
* Function: Cannonball
*Usage:n=Cannonball(height);
* ------------------------------
*Thisfunctioncomputesthenumberofcannonballsinastack
*thathasbeenarrangedtoformapyramidwithonecannonball
*atthetopsittingon topofasquarecomposedoffour
*cannonballssittingontopofasquarecomposedofnine
*cannonballs,andsoforth. ThefunctionCannonballcomputes
*thetotalnumberbasedontheheightofthestack.
*/
staticintCannonball(intheight)
{
if(height==0) {
return(0);
}else{
return (height * height + Cannonball(height - 1));
}
}
Problem 2: ReverseString
staticstringReverseStringRecursive(stringstr)
{if(str.length()==0)
{
return"";
}
returnReverseStringRecursive(str.substr(1))+ str[0];
}
staticstringReverseStringIterative(stringstr)
{
stringresult="";
for(inti=str.length() -1;i>=0;i--)
{
result+=str[i];
}
returnresult;
}
Which one is easier to come up with? The recursive one, of course!
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
22/221
2
Problem 3: GCD
static int GCD(int x, int y)
{
if ((x % y) == 0)
{
return y;}
else
{
return GCD (y, x % y);
}
}
Problem 4: Old-Fashioned Measuring (Chapter 5, Programming Exercise 10)
static bool IsMeasurable(int target, int weights[], int nWeights)
{
return RecIsMeasurable(target, weights, nWeights, 0);
}
static bool IsMeasurable(int target, int weights[], int nWeights, int currentWeight)
{
if (target == 0)
return true;
if (currentWeight >= nWeights)
return false;
return (RecIsMeasurable(target + weights[currentWeight], weights,
nWeights, currentWeight + 1)
|| RecIsMeasurable(target, weights, nWeights, currentWeight + 1)
|| RecIsMeasurable(target - weights[currentWeight], weights,
nWeights, currentWeight + 1));
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
23/221
3
Problem 5: List Mnemonics
/*
* Function: ListMnemonics
*Usage:ListMnemonics(str);
*--------------------------
*Thisfunctionlistsallofthemnemonicsforthestringofdigits
*storedinthestringstr. Thecorrespondencebetweendigitsand
*lettersisthesameasthatonthestandardtelephonedial. The
*implementationat thislevelisasimplewrapperfunctionthat
* provides the arguments necessary for the recursive call.
*/
staticvoidListMnemonics(string str)
{
RecursiveMnemonics("",str);
}
/*
*Function:RecursiveMnemonics
*Usage:RecursiveMnemonics(prefix,rest);
*----------------------------------------
* This function does all of the real work for ListMnemonics and
*implementsamore generalproblemwitharecursivesolution
*thatiseasierto see. ThecalltoRecursiveMnemonicsgenerates
*allmnemonicsfor the digitsinthestring restprefixedbythe
*mnemonicstringinprefix. Astherecursionproceeds,therest
*stringgetsshorterandtheprefixstringgets longer.
*/
staticvoidRecursiveMnemonics(stringprefix,stringrest){
if(StringLength(rest)==0){
cout
-
7/30/2019 stanford handout
24/221
4
/*
*Function:DigitLetters
* Usage: digits = DigitLetters(ch);
*---------------------------------
*Thisfunctionreturns astringconsistingofthelegal
*substitutionsfor agivendigitcharacter.Notethat0and*1arehandledjustby leavingthatdigitinitsposition.
*/
staticstringDigitLetters(charch)
{
switch(ch){
case'0':return ("0");
case'1':return ("1");
case'2':return ("ABC");
case '3': return ("DEF");
case'4':return ("GHI");
case'5':return ("JKL");case'6':return ("MNO");
case'7':return ("PRS");
case'8':return ("TUV");
case'9':return ("WXY");
default: Error("Illegal digit");
}
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
25/221
5
Problem 6: Spot the Bug
The bug occurs becausemyArray is passed into DoubleArrayLength by value rather than byreference.ThismeansthatchangestothevariablearrayinDoubleArrayLengtharenotseenby
myArrayinmain. This seems a little counter intuitive since array is a pointer, and we say that apointer allows changes to be seen by the caller. What happens is that any changes to elements of
thearraywillbeseen,butDoubleArrayLengthchangesnottheelementsofthearraybutwherethe array is in the first place. Here is a picture, in case that helps:
Note that the value ofmyArray itself has not been changed by a call to DoubleArrayLength. To fix
this,wedothesamethingthatwealwaysdotoallowafunctiontochangethevariablespassedto it in a way that the caller sees the changeswe use a reference! All we have to do is changethe prototype to DoubleArrayLength to the following and all ofour troubles go away:
staticvoidDoubleArrayLength(int*&array,intlength)
To help you understand int *&array, read it from the right. array is a reference to a pointertoan integer.
5
1
1
DoubleArrayLength
main
Stack Heap
array
length
myArray
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
26/221
CS106B Handout #13Winter 05-06 January 23, 2006
Section Handout #2
Problem 1: Memory Diagrama) Trace through the following bit of code and draw a diagram showing the contents ofmemory at the indicated point. Be sure to differentiate between the stack and the heap.
struct nameT {
string name;
int level;
};
struct groupT {
nameT lidda[2];
nameT *jozan;
nameT *devis[2];};
void Mialee(groupT tordek, int &level)
{
tordek.lidda[1].name = Hennet;
tordek.lidda[1].level = 10;
tordek.devis[0] = &tordek.jozan[1];
level += 5;
tordek.devis[0]->level = level + tordek.devis[1]->level;
tordek.devis[0]->name = tordek.lidda[1].name.substr(3, 2) + bit;
/* DRAW THE STATE OF MEMORY HERE */
}
int main()
{
groupT tordek;
tordek.lidda[0].name = Ember;
tordek.lidda[0].level = 2;
tordek.lidda[1].name = Krusk;
tordek.lidda[1].level = 3;
tordek.jozan = new nameT[2];
tordek.devis[0] = NULL;
tordek.devis[1] = &tordek.jozan[0];
*tordek.devis[1] = tordek.lidda[1];
Mialee(tordek, tordek.lidda[1].level);
return 0;
}
b) What would happen instead iftordek were passed by reference instead of by value?This would make the prototype for Mialee:
void Mialee(groupT &tordek, int &level)
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
27/221
2
Problem 2: ArraysWrite a functionCountLetters that takes an array of strings and counts the number oftimes each letter of the alphabet appears. Because there are 26 numbers to be returned,CountLetters needs to return an array. For example, if we provide the following array:
abcd ijk cabbage fad
CountLettersshould return the following:
4 3 2 2 1 1 1 0 1 1 1 0
Note that this array should be 26 elements long, but that we couldn't easily display thaton the page. Before writing theCountLetters function, you should decide if the array itreturns needs to be dynamically allocated. You should use the following prototype, andyou may assume that the array you are passed contains only lowercase letters and noother characters.
int *CountLetters(string words[], int numWords);
Problem 3: Spot the BugWhile debugging some code, you narrow your search down to the followingDoubleArrayLength function. Trace through a call to the following function to find thebug. Once you have found the bug, determine what should be done to fix it.
/* The following function doubles the length of an array of integers */
void DoubleArrayLength(int *array, int length)
{
int *newArray = new int[length * 2];
for (int i = 0; i < length; i++)
{
newArray[i] = array[i];
}
for (int i = length; i < length * 2; i++)
{
newArray[i] = 0;
}
array = newArray;
}
int main()
{int *myArray = new int[5];
for (int i = 0; i < 5; i++)
{
myArray[i] = i;
}
DoubleArrayLength(myArray, 5);
cout
-
7/30/2019 stanford handout
28/221
3
return 0;
}
Problem 4: What kind of structures do you like?You need to store a collection of a particular type of structure. In general, think about thedifferences between declaring a static array of the structures, a dynamic array of thosestructures, and a static array of pointers to those structures. In what cases would you want
to use each of these approaches?
Problem 5: Data StructuresYou're going to read credit card billing information from a file that is organized like this:
Kermit the Frog name of credit card holder
12number of charges this monthMacy'sproprietor for a charge123.45amount of chargeTower Recordsetc.45.12.... 10 more charges here ...Bill Gatesnext record follows immediately after the end120Fry's Electronics
12345.60... etc. ...
A blank line will follow the last client in the file to signify the end.
There can be up toMAX_RECORDSrecords in the file, but is likely to be a lot less, so you
don't really want to pre-allocate any records. You will have a complete array of structpointers, and you should use newto create actual structures only when needed. There is
no limit on the number of charges that may be billed for each person.
Design the data structure for this database and write the functions needed to read thisinformation from the file. How would you free the memory allocated for the datastructure you designed?
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
29/221
4
Problem 6: CannonballsSuppose that you have somehow been transported back to 1777 and the RevolutionaryWar. You have been assigned a dangerous reconnaissance mission: evaluate the amountof ammunition available to the British for use with their large cannon which has been
shelling the Revolutionary forces. Fortunately for you, the Britishbeing neat andorderlyhave stacked the cannonballs into a single pyramid-shaped stack with onecannonball at the top, sitting on top of a square composed of four cannonballs, sitting ontop of a square composed of nine cannonballs, and so forth. Unfortunately, however, theRedcoats are also vigilant, and you only have time to count the number of layers in thepyramid before you are able to escape back to your own troops. To make matters worse,computers will not be invented for at least 150 years, but you should not let that detail getin your way. Your mission is to write a recursive function Cannonball that takes as itsargument the height of the pyramid and returns the number of cannonballs therein.
int Cannonball(int height);
Problem 7: GCDThe greatest common divisor (g.c.d.) of two nonnegative integers is the largest integerthat divides evenly into both. In the third century B.C., the Greek mathematician Eucliddiscovered that the greatest common divisor of x and y can always be computed asfollows:
If x is evenly divisible by y, then y is the greatest common divisor. Otherwise, thegreatest common divisor of x and y is always equal to the greatest commondivisor of y and the remainder of x divided by y.
Use Euclid's insight to write a recursive function int GCD(int x, int y)that
computes the greatest common divisor of x and y.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
30/221
CS106B Handout #13SWinter 05-06 January 23, 2006
Section Solutions #2
Problem 1: Memory Diagram
STACK HEAP
main
tordek
name
level
2
Ember
name
level
8
Krusklidda
jozan
devis
name
level
3
Krusk
Mialee
tordek
name
level
2
Ember
name
level
10
Hennetlidda
jozan
devis
level
level
11
name
nebit
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
31/221
b) Iftordek were passed by reference, all of the changes made to tordek inside of
Mialee would be seen by main. It is also important to note that this would have some
interesting effects upon tordek.lidda[1].level. Once tordek is passed by reference, both
tordek.lidda[1].level and level would refer to the same location in memory, soessentially, changing one would change the other.
STACK HEAP
main
tordek
name
level
2
Ember
name
level
15
Hennetlidda
jozan
devis
name
level
3
Krusk
name
level
18
nebit
level
Mialee
tordek
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
32/221
Problem 2: ArraysTo be able to return an array, it needs to be created dynamically. Remember that an array
is simply a pointer, so if we return a static array, we are really just returning a pointer to
memory on the stack which is deallocated when the function ends.
#define ALPHABET_SIZE 26
int *CountLetters(string words[], int numWords){
int *result = new int[ALPHABET_SIZE];
for (int i = 0; i < ALPHABET_SIZE; i++)result[i] = 0; // must initialize contents!
for (int i = 0; i < numWords; i++){
for (int j = 0; j < words[i].length(); j++)
{int index = words[i][j] a;result[index]++;
}}
return result;}
Problem 3: Spot the Bug
The bug occurs becausemyArrayis passed into DoubleArrayLengthby value rather than
by reference. This means that changes to the variable array in DoubleArrayLengthare
not seen bymyArrayinmain. This seems a little counter intuitive since array is a pointer,and we say that a pointer allows changes to be seen by the caller. What happens is that
any changes to elements of the array will be seen, but DoubleArrayLengthchanges not theelements of the array but where the array is in the first place. Here is a picture, in casethat helps:
STACK HEAP
5
main
0 1 2 3 4
0 1 2 3 4
0 0 0 00
DoubleArrayLength
array
length
myArray
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
33/221
Note that the value ofmyArrayitself has not been changed by a call to DoubleArrayLength.
To fix this, we do the same thing that we always do to allow a function to change the
variables passed to it in a way that the caller sees the changeswe use a reference! All
we have to do is change the prototype to DoubleArrayLengthto the following and all of
our troubles go away:
static void DoubleArrayLength(int *&array, int length)
To help you understand int *&array, read it from the right. array is a reference to apointerto an integer.
Problem 4: What kind of structures do you like?
Static array: + No dynamic allocation, don't have to work with pointers, can
grow/shrink number of elements used (within bounds of the array)- The fixed upper bound means potentially too small or too large,
can waste a lot of space or limit utility value
Dynamic array: + Exactly the size you need, as little or as large- Have to remember to allocate & thus must know size in advance,
can't grow/shrink easily once allocated
Static array of ptrs: + Moderately conservative in use of memory, can grow/shrinkwithin bounds of array, pointers are easier to swap and move
around inside array
- Lots of allocations means lots of opportunities to forget, still have
fixed upper limit problems, forces you to deal with pointers
Any decision among these three choices should consider such factors as the size of the
structure itself, how large the variance is in the number of elements needed, howcomfortable you feel about working with pointers, whether this is a known upper bound
that is never exceeded, whether you need to grow and shrink the array, and so on.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
34/221
Problem 5: Data Structures
struct chargeRec
{string proprietor;double amount;
};
struct cardHolder
{string name;chargeRec *chargeArray; // dynamically-allocated array of charges
int numCharges; // num elements in above array
};
struct billingDB
{cardHolder *cardHolderArray[MAX_RECORDS]; // array of ptr to
// cardHoldersint numCardHolders; // effective size of above array
};chargeRec ReadCharge(ifstream& in){
chargeRec charge;string line;
getline(in, charge.proprietor);
getline(in, line);charge.amount = StringToReal(line);
return charge;
}
// The reading and freeing functions are on the next pagecardHolder *ReadCardHolder(ifstream& in){
string line;cardHolder *client;
getline(in, line);
if (line == "") return NULL;
client = new cardHolder;client->name = line; // makes a copy of the line
getline(in, line);client->numCharges = StringToInteger(line);
/* dynamically allocate the charge array now that we know the
size */client->chargeArray = new chargeRec[client->numCharges];for (int i = 0; i < client->numCharges; i++) {
client->chargeArray[i] = ReadCharge(in);
}
return client;
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
35/221
}billingDB *ReadBillingDB(ifstream& in){
cardHolder *client;billingDB *db;
db = new billingDB;db->numCardHolders = 0;
for (int i = 0; i < MAX_RECORDS; i++) {client = ReadCardHolder(in);
if (client == NULL) break; // no more clientsdb->cardHolderArray[i] = client;db->numCardHolders++;
}
return db;}
This data structure has lots of storage to free the charge arrays themselves, the cardholder records, etc. Be sure to free things in the correct order (free things pointed to out
of structures before freeing those structures themselves).
void FreeCardHolder(cardHolder *client)
{delete[] client->chargeArray; // free dynamic array itselfdelete client; // free cardHolder structure
}void FreeBillingDB(billingDB *db){
for (int i = 0; i < db->numCardHolders; i++) {
FreeCardHolder(db->cardHolderArray[i]);}delete db;
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
36/221
Problem 6: Cannonballs/*
* Function: Cannonball
* Usage: n = Cannonball(height);* ------------------------------* This function computes the number of cannonballs in a stack
* that has been arranged to form a pyramid with one cannonball* at the top sitting on top of a square composed of four
* cannonballs sitting on top of a square composed of nine* cannonballs, and so forth. The function Cannonball computes
* the total number based on the height of the stack.*/
int Cannonball(int height){
if (height == 0) {return (0);
} else {return (height * height + Cannonball(height - 1));
}}
Problem 7: GCD
int GCD(int x, int y){
if ((x % y) == 0){
return y;
}
else{
return GCD (y, x % y);}
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
37/221
CS106B Handout #14Spring 05-06 April 19, 2006
Section Handout #2
Problem 1: Using the Scanner and Stack classes
CS106 rules!
Web browsers use stacks to track html tags such as , or . Every html tagmust be matched by an equivalent closing tag -- , or . Microsoft is lookingfor programmers to help implement this feature in the next version of Internet Explorerand you, armed with your newly acquired knowledge of classes, decide to volunteer forthe job. Using the Scanner class (from A-21 in the reader) and the Stack class (A-27),write the following function:
bool IsCorrectlyNested(string htmlStr);
You can assume that all the tags in the html string will be correctly formed. That is, onceyou see an angle bracket, it will be followed by the remainder of a complete and well-formed tag (So, nothing like
-
7/30/2019 stanford handout
38/221
2
c)How could you modify the to field of the eMailMsg structure so that it can hold theemail addresses of an arbitrary number of recipients of an email? With the modificationin place, given an eMailMsg email, how would you access the last address listed in the
to field?
Problem 4: Data Structure Design
Apple has decided to release new software for the iPod, and since everyone in 106B hasjust learned about data structures and pointers, decides to ask for your help with thedesign decisions. For simplicity, each song only needs to store the album, artist, andgenre associated with it.
a.) How would you design the data structure to represent a song and the list of songsstored on an iPod?
b.) Just viewing songs is fun, but Apple also wants the user to be able to have multipleviews on the same data. For instance, the user should be able to view by album, by artistor by genre. How would you create the data structures to do this?
c.) Now suppose the user connects their iPod to their computer and a song needs to beadded to the iPod. What needs to be updated in the data structures to allow this tohappen? Also, what happens in the case of deleting? Does your design from parts a andb easily allow you to add and delete? If not, what changes would you make so that theseoperations would be easier/more efficient?
Problem 5: Symbol Table Warm-up
Write a function:
char MostFrequentCharacter(ifstream &if, int &numOccurrences);
that given an input file stream, returns the character that occurs the most frequently andstores the number of times it occurs in the reference parameter numOccurrences. To
write this function, first start by scanning through the file stream, analyzing eachcharacter and storing an updated count in a symbol table. Then, after youve built thistable, iterate over it to find the character that occurred the most often. (Note that unlikelast weeks problem of counting the letters in an array of strings, by using the symboltable we dont need to restrict ourselves to just lowercase letters.)
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
39/221
CS106B Handout #14S
Spring 05-06 April 19, 2006
Section Solutions #2
Problem 1: Using the Scanner and Stack classes
#include "stack.h"#include "scanner.h"
bool ProcessOpenTag(Scanner *scanner, Stack *tagStack)
{string tag = scanner->ReadToken();tagStack->Push(tag);
return true;
}
bool ProcessCloseTag(Scanner *scanner, Stack *tagStack){string tag = scanner->ReadToken();
if (!tagStack->IsEmpty() && tag == tagStack->Pop()) {
return true;
}else {return false;
}}
bool ProcessTag(Scanner *scanner, Stack *tagStack){
// read the next token to see if we found an
// opening or closing tagstring token = scanner->ReadToken();
if (token == "/")
{return ProcessCloseTag(scanner, tagStack);
}
else{
scanner->SaveToken(token);return ProcessOpenTag(scanner, tagStack);
}
}
bool IsCorrectlyNested(string htmlStr){
Scanner *scanner = new Scanner();
scanner->SetSpaceOption(Scanner::IgnoreSpaces);
Stack *tagStack = new Stack();scanner->SetScannerString(htmlStr);
// start by assuming it is balanced
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
40/221
bool isBalanced = true;
while (scanner->MoreTokensExist()){
string token = scanner->ReadToken();
if (token == "" part of tagscanner->ReadToken();
}
}
if (!tagStack->IsEmpty()) isBalanced = false;
delete scanner;
delete tagStack;return isBalanced;
}
Problem 2: Queues
/**
* The client version of reverse queue. In order* to change the order of elements in the queue,
* we use an external stack*/
void ReverseQueue(Queue* queue) {Stack* stack = new Stack();while (!queue->IsEmpty())
stack->Push(queue->Dequeue());while (!stack->IsEmpty())
queue->Enqueue(stack->Pop());
delete stack;
}
Problem 3: Vectors
a)Vector *mailVector = new Vector();
b)
void RemoveSpam(Vector *v) {for (int i = 0; i < v->Length(); i++) {
eMailMsg mail = v->ElementAt(i);
if (mail.subject.find("SPAM") == 0) {v->RemoveAt(i);i--; // look at this index again,
// since elements have been shifted down}
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
41/221
}
Note that you also could move backwards down the vector and not have to worry about
decrementing i.
c) We use another Vector, of course!
struct eMailMsg {Vector *to;
string from;string message;string subject;
int date;int time;
};
Access to the last element ofeMailMsg email would be done by:
string lastAddress = email.to->ElementAt(email.to->Length() 1);
Problem 4: Data Structure Design
a.) To store song information we could create something as follows:
struct songT{
string name;
string album;string artist;
string genre;
char *data;
};
and then to store the collection of songs, we could simply turn to the Vector class:Vector *songs;
b.) To create multiple views, we could define our data structures as below:
struct albumT{
string albumName;
Vector *songs;};
struct artistT{
string artistName;
Vector *songs;
};
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
42/221
typedef enum genreTypeT { Rap, Rock, Jazz, Classical };
struct genreT
{genreTypeT genre;
Vector *songs;};
And then to have multiple views on the data, we simply need to store Vectors of theabove information:
Vector *artists;Vector *albums;
Vector *genres;
In each of the above, we make heavy use of the Vector to help store all of our data. Note
that in all of the structures, we store a pointer to the songT when storing a list of songs.
This lets us just have one copy of each song, and then reuse the data associated with thatsong. If each of the above structures just stored a songT in their vectors rather than apointer to one, then they each would have a copy of the contents of the songT. This
would cause us to store a lot of redundant data Also, if the song name was accidentally
mistyped, we only need to change the data in that song for everyone else to notice thechange, rather than having to search through everything to find matches to that song.
It also might be helpful to store all of the vectors in sorted order. This would allow forconvenient browsing, but also would mean wed need to do a little extra work to make
sure the array was sorted (for instance, by inserting new songs in to the array in their
correct alphabetic position).
Also, with these new data structures, we can change up our songT slightly. Rather thanstoring the name of the album, artist and genre, we can leverage the fact that we now
have data structures to store this information, and can point to the associated data
structure for each field. Now, if we have a song and want to find the other songs in thesame genre, we simply need to follow a pointer to find out all this information.
struct songT
{string name;albumT *album;
artistT *artist;genreT *genre;
char *data;};
c.) To add a song, we need to create a new songT. To do so well need to find the album,
artist and genre the song is associated with (or create them if they dont exist). After
which well want to add the songT to the list of songs, as well as to the album, artist andgenre it belongs to. To delete a song we simply need to look it up, and them remove it
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
43/221
from all the views it is associated with. Our use of the Vector means all of these
operations are fairly easy. If we chose to store raw arrays, wed have a lot more work todo in terms of organizing our data: wed have to make sure to have enough memory
allocated, shuffle array elements depending on where we inserted or deleted, make sure
to stay in bounds, etc
Problem 5: Symbol Table Warm-up
char MostFrequentCharacter(ifstream &in, int &numOccurrences){
Symtab *charFrequencies = new Symtab;
while (true){
// get the next character from the stream
int nextChar = in.get();if (nextChar == EOF)
{
break;}
// convert it to a string for lookup in the symbol table
string foundChar = "";foundChar += char(nextChar);
// if we find it, incremement the stored value, otherwise// enter in a new one
int frequency = 1;if (charFrequencies->Lookup(foundChar, frequency)){
charFrequencies->Enter(foundChar, frequency + 1);
}
else{
charFrequencies->Enter(foundChar, frequency);
}}
// now use an iterator to find the most occurring characterIterator *it = charFrequencies->CreateIterator();
string maxCharacter = "";
while (it->HasNext()){
string character = it->Next();
int frequency;
charFrequencies->Lookup(character, frequency);
if (frequency > numOccurrences)
{maxCharacter = character;
numOccurrences = frequency;}
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
44/221
delete it;
delete charFrequencies;
return maxCharacter[0];}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
45/221
CS106B Handout #16
Spring 06-07 April 16, 2007
Section Handout #2
Problem 1: Vectors (AKA C++ ArrayLists)Say we are writing the next version of Eudora and want to use a Vector (interface in
reader appendix) to store all the data. The following structure is used to hold the data ofan email message:
struct eMailMsg {
string to; // i.e. "[email protected]"
string from; // i.e. "[email protected]"
string message; // body of message
string subject; // i.e. "CS106 Rocks!"
int date; // date email was sent
int time; // time email was sent
};
a)How would you declare aVectorthat stores eMailMsgs?
b)Write a function RemoveSpamthat takes a vector containing elements of type
eMailMsgand removes all elements whose subject begins with the string "SPAM".
c)How could you modify the tofield of the eMailMsgstructure so that it can hold the
email addresses of an arbitrary number of recipients of an email? With the modificationin place, given an eMailMsgemail, how would you access the last address listed in the
tofield?
Problem 2: QueuesWrite a function
void ReverseQueue(Queue & q);
that reverses the elements in the passed in queue. (Hint: Is there another class that couldmake doing this a lot easier?)
Problem 3: Map Warm-up
Write a function:
char MostFrequentCharacter(ifstream & if, int & numOccurrences);
that given an input file stream, returns the character that occurs the most frequently and
stores the number of times it occurs in the reference parameter numOccurrences. To
write this function, first start by scanning through the file stream, analyzing eachcharacter and storing an updated count in a map. Then, after youve built this table,
iterate over it to find the character that occurred the most often.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
46/221
2
Problem 4: Crossword PuzzleA crossword puzzle solution is represented as a grid of characters, using an asterisk to
indicate blackout squares, as shown in the example below:
(0,0)
* M E S S * * R O T * S H A V E *
* E C H O * L O C I * Y O D E L ** * R O O M * A D V A N T A G E *
* N U T T Y * D * O L E * G A G *
* * * * H * * * * L A R C E N Y *
* A N T E * E A T I N G * * * * *
* N O O S E * * * * * Y A C H T *
You are to write the function AcrossWords that builds a vector containing the words that
read across in the puzzle solution. Each sequence of two or more characters bounded byasterisks forms a word. For example, in the puzzle above, the words "MESS", "ROT",and "SHAVE" read across the top row. There will always be an asterisk in the first and
last columns of every row of the puzzle.
The one parameter to AcrossWords is the grid with the puzzle solution (passed byreference.) The function returns a vector of strings where the vector elements are the
words that read across in the order found when processing the puzzle from top-left tobottom-right.
Vector AcrossWords(Grid & puzzle)
The Grid interface is found in the reader's appendix.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
47/221
CS106B Handout #16S
Spring 06-07 April 18, 2007
Section Solutions #2
Problem 1: Vectorsa)Vector mailVector;
b)void RemoveSpam(Vector & v) {
for (int i = 0; i < v.size(); i++) {eMailMsg mail = v[i];
if (mail.subject.find("SPAM") == 0) {v.removeAt(i);
i--; // look at this index again,// since elements have been shifted down
}}
}
Note that you also could move backwards down the vector and not have to worry about
decrementing i.
c) We use another Vector, of course!
struct eMailMsg {
Vector to;string from;
string message;string subject;int date;
int time;};
Access to the last element ofeMailMsg email would be done by:
string lastAddress = email.to[email.to.size() 1];
Problem 2: Queues
/**
* The client version of reverse queue. In order* to change the order of elements in the queue,
* we use an external stack*/
void ReverseQueue(Queue & queue) {Stack stack;while (!queue.isEmpty())
{
stack.push(queue.dequeue());}
while (!stack.isEmpty())
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
48/221
{queue.enqueue(stack.pop());
}}
Problem 3: Symbol Table Warm-up
void CountOccurrences(ifstream & in, Map & charFrequencies){
while (true){
// Note: we need to store the result in an int, not a charint nextChar = in.get();
if (nextChar == EOF){
break;}
// convert it to a string for lookup in the symbol table
string foundChar = "";foundChar += char(nextChar);
int frequency = 1;if (charFrequencies.containsKey(foundChar))
{
frequency = charFrequencies[foundChar] + 1;}charFrequencies[foundChar] = frequency;
}}
char MostFrequentCharacter(ifstream & in, int & numOccurrences)
{
Map charFrequencies;numOccurrences = 0;
CountOccurrences(in, charFrequencies);
Map::Iterator it = charFrequencies.iterator();string maxCharacter = "";
while (it.hasNext()){
string character = it.next();
int frequency = charFrequencies[character];
if (frequency > numOccurrences)
{maxCharacter = character;
numOccurrences = frequency;}
}
return maxCharacter[0];}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
49/221
Problem 4: Crossword Puzzle
Vector AcrossWords(Grid & puzzle)
{Vector words;
for(int row = 0; row < puzzle.numRows(); row++){bool buildingWord = false;
string curWord = "";
for(int col = 0; col < puzzle.numCols(); col++)
{
char ch = puzzle(row, col);if(ch == '*'){
//Are we building a word? If so, store and resetif(buildingWord)
{if(curWord.length() >= 2)
{words.add(curWord);
}curWord = "";
buildingWord = false;}
}else
{buildingWord = true;curWord += ch;
}}
}
return words;}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
50/221
Mehran Sahami Handout #19CS106B April 14, 2008
Section Handout #2
Problem 1: Quick Pointer Questions.
Take this crash course test on pointers and memory: which of the following would causecompile-time or run-time problems? Also, what types are the left and right hand sides ofeach expression?
double x, *px, a[5];
x = *px; /* 1 */*px = x; /* 2 */px = &x; /* 3 */&x = px; /* 4 */&(x+1) = x; /* 5 */&x + 1 = x; /* 6 */
*(&(x+1)) = x; /* 7 */*(&(x)+1) = x; /* 8 */x = a; /* 9 */x = a[0]; /* 10 */x = *(a[1]); /* 11 */x = (*a)[2]; /* 12 */x = a[3+1]; /* 13 */x = a[3] +1; /* 14 */x = &((a[3])+1); /* 15 */x = &(a[3]) +1; /* 16 */x = *(&(a[3])+1); /* 17 */px = a; /* 18 */px = a[0]; /* 19 */px = &(a[4]); /* 20 */
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
51/221
2
Problem 2: Memory DiagramDraw a diagram showing the contents of memory at the indicated point. Be sure todifferentiate between the stack and the heap.
void HousingDraw(double **flomo, int lag, double wilbur[],int* & roble)
{
int* stern;int** govCo;
stern = new int[2];govCo = &stern;stern[0] = sizeof(stern) / 3;stern[1] = stern[0] * 3;*flomo = new double[lag];roble = new int[2];
wilbur++;*(wilbur + 1) = 4;for(lag = 0; lag < *wilbur; lag++) {
wilbur[lag] = wilbur[lag] / 2;}roble = *govCo;
}
int main(){
int* toyon;double *kimball, branner[3];
for(int i = 0; i < 3; i++) {branner[i] = 6 / (i + 1);
}
HousingDraw(&kimball, branner[2], branner, toyon);
return 0;}
Draw a diagram indicating the contents of memory at this point
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
52/221
3
Problem 3: 2-D ArraysWrite a functionMake2D that takes a one-dimensional array, a row size, and a column size,and returns a 2-D array from the numbers in the first array. Make sure that your functioncan deal with arrays of different dimensions. You can also assume that there will beenough data in the array to fill the 2-D array of the specified size (i.e. there will be at leastrow * col elements in the one-dimensional array)
For example, if we provide the following array:
3.7 8.2 4.0 9.5 2.7 6.4 9.8 5.4 9.1 3.5 5.6 7.8 8.7 2.0 9.4 7.1
And the row and column dimensions 4 and 4, we should get a pointer to a dynamicallyallocated array that looks like this:
The prototype is as follows:
double** Make2D(double array[], int rows, int cols);
eap
8.2
4.0
9.5
3.7
9.1
3.5
5.6
7.8
8.7
2.0
9.4
7.1
2.7
6.4
9.8
5.4
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
53/221
4
Problem 4: CD TroublesConsider the following declaration, which declares a type for a compact disc that is thetitle of the disc, as well as a dynamic array of the track titles:
struct CDtype {string title;string *trackTitles;
int numTracks;};
Assume that we have a function void ReadCD(CDtype& cd) that will read in one CD worthof info from a file: read the CD title, dynamically allocate the array of track titles and readthem in. Now, assume that we have two CDs that are identical, except for the title of thefirst song. We try creating the two CD structs using the following code, but something isfishy herewhat is it?
int main(){
CDtype cd1, cd2;
ReadCD(cd1); // read all info about cd1cd2 = cd1; // make cd2 a copy of the cd1 structcd2.trackTitles[0] = "Layla"; // change 1st song in cd2return 0;
}
Problem 5: What kind of structures do you like?You need to store a collection of a particular type of structure. In general, think about thedifferences between declaring a static array of the structures, a dynamic array of thosestructures, and a static array of pointers to those structures. In what cases would you want
to use each of these approaches?
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
54/221
5
Problem 6: Data StructuresYou're going to read credit card billing information from a file that is organized like this:
Kermit the Frog name of credit card holder
12 number of charges this month
Macy's proprietor for a charge
123.45 amount of charge
Tower Records etc.45.12
.... 10 more charges here ...Bill Gates next record follows immediately after the end120
Fry's Electronics
12345.60
... etc. ...
A blank line will follow the last client in the file to signify the end.
There can be up toMAX_RECORDS records in the file, but is likely to be a lot less, so you
don't really want to pre-allocate any records. You will have a complete array of structpointers, and you should use new to create actual structures only when needed. There isno limit on the number of charges that may be billed for each person.
Design the data structure for this database and write the functions needed to read thisinformation from the file. How would you free the memory allocated for the datastructure you designed?
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
55/221
Mehran Sahami Handout #19SCS106B April 14, 2008
Section Solutions #2
Problem 1: Quick Pointer Questions.
Here are the answers for these questions legal means it will compile, and illegal means that thecompiler will generate an error:
Number Expression Compiles? Leftsidetype
Rightsidetype
1 x = *px; Legal double double2 *px = x; Legal double double3 px = &x; Legal double* double*4 &x = px; Illegal- &x cant be assigned N/A double*5 &(x+1) = x; Illegal same reason as #4 N/A double6 &x + 1 = x; Illegal same reason as #4 N/A double7 *(&(x+1)) = x; Illegal cant take &(x + 1) N/A double8 *(&(x)+1) = x; Legal stores into the variable
after x on the stack. This willcause run-time problems!
double double
9 x = a; Illegal types dont match double double*10 x = a[0]; Legal double double11 x = *(a[1]); Illegal a[1] is not a pointer double N/A12 x = (*a)[2]; Illegal (*a) is a double, which
means we cant use arrayreferences on it.
double N/A
13 x = a[3+1]; Legal double double14 x = a[3] +1; Legal double double15 x = &((a[3])+1); Illegal cant take the address
of a number or expressiondouble N/A
16 x = &(a[3]) +1; Illegal types dont match double double*17 x = *(&(a[3])+1); Legal means the same thing as
x = a[4]double double
18 px = a; Legal double* double*19 px = a[0]; Illegal types dont match double* double20 px = &(a[4]); Legal double* double*
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
56/221
2
Problem 2: Memory Diagram
Problem 3: 2-D ArraysNote that since C++ uses memory in a row-major format, we start by creating an array ofdouble*'s to hold all the rows, and then fill in the numbers by column.
double** Make2D(double array[], int nRows, int nCols){
double** result;
result = new double*[nRows];
for (int i = 0; i < nRows; i++) {result[i] = new double[nCols];for (int j = 0; j < nCols; j++) {
result[i][j] = array[(i * nCols) + j];}
}
return result;}
Problem 4: CD Troubles
The problem is that each CDtype variable contains a dynamic array of strings, which is actually apointer. So when we copy CD1 into CD2, everything gets copied exactly, including the base
address of the array, which means that both CD1 and CD2 are pointing to the same array oftrackTitles. In changing the title of the first song on CD2, we will inadvertently change the
title for CD1 also. In order to create a copy of a CDtype that is entirely distinct, we need toallocate memory for the new trackTitles array, and then copy each title individually. (This
structure copy operation would make a really good function!)
Stack eap
ain
toyonkimball
branner
Orphaned!
6.0
1.5
2.0
1
3
???
???
???
???
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
57/221
3
Problem 5: What kind of structures do you like?
Static array: Pros: No dynamic allocation, don't have to work with pointers, can usedifferent number of elements in the array (within bounds of the array).
Cons: The fixed upper bound means potentially too small or too large, canwaste a lot of space or limit utility value.
Dynamic array: Pros: Exactly the size you need, as little or as large.
Cons: Have to remember to allocate memory for array before referring tothe elements of the array, and the deallocate memory when you done withit.
Static array of ptrs: Pros: Moderately conservative in use of memory, can use different numberof elements in the array within bounds of array, pointers are easier to swapand move around inside array.
Cons: Lots of allocations means lots of opportunities to forget, still havefixed upper limit problems, forces you to deal with pointers.
Any decision among these three choices should consider such factors as the size of the structureitself, how large the variance is in the number of elements needed, how comfortable you feelabout working with pointers, whether this is a known upper bound that is never exceeded,whether you need to grow and shrink the array, and so on.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
58/221
4
Problem 6: Data Structures
struct chargeRec {string proprietor;double amount;
};
struct cardholder {string name;int numCharges;chargeRec *chargeArray; // dynamically-allocated array of charges
};
struct billingDB {int numCardHolders;cardHolder *cardHolderArray[MAX_RECORDS];
// array of ptr to cardHolders};
chargeRec ReadCharge(ifstream& in){
chargeRec charge;string line;
getline(in, charge.proprietor);getline(in, line);charge.amount = StringToReal(line);
return charge;}
cardHolder *ReadCardHolder(ifstream& in){
string line;cardHolder *client;
getline(in, line);if (line == "") return NULL;
client = new cardHolder;client->name = line; // makes a copy of the linegetline(in, line);client->numCharges = StringToInteger(line);
/* dynamically allocate the charge array now that we know the size */client->chargeArray = new chargeRec[client->numCharges];for (int i = 0; i < client->numCharges; i++) {
client->chargeArray[i] = ReadCharge(in);}return client;
}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
59/221
5
billingDB *ReadBillingDB(ifstream& in){
cardHolder *client;billingDB *db;
db = new billingDB;
db->numCardHolders = 0;for (int i = 0; i < MAX_RECORDS; i++) {client = ReadCardHolder(in);if (client == NULL) break; // no more clientsdb->cardHolderArray[i] = client;db->numCardHolders++;
}return db;
}
This data structure has lots of storage to free the charge arrays themselves, the card holderrecords, etc. Be sure to free things in the correct order (free things pointed to out of structures
before freeing those structures themselves).void FreeCardHolder(cardHolder *client){
delete[] client->chargeArray; // free dynamic array itselfdelete client; // free cardHolder structure
}
void FreeBillingDB(billingDB *db){
for (int i = 0; i < db->numCardHolders; i++) {FreeCardHolder(db->cardHolderArray[i]);
}
delete db;}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
60/221
Eric Roberts Handout #17CS106B April 13, 2009
Section Handout #2ADTs
Problem 1. Using grids
In the game of Minesweeper, a player searches for hidden bombs on a rectangular grid.The game board is represented by a grid of booleans marking bomb locations. A gridvalue is true if there is bomb at that location, false otherwise. Here is an example grid:
(0,0)
T F F F F T
F F F F F T
T T F T F T
T F F F F F
F F T F F F
F F F F F F
Given such a grid of bomb locations, the function
void MakeGridOfCounts(Grid & locations, Grid & counts);
should construct a grid of integers storing the count of bombs in each neighborhood. Theneighborhood for a location includes the location itself and its eight adjacent locations,but only if they are inside the dimensions of the grid. The reference parameter counts isused to store the result; your job is to make sure that it has the same size as thelocations grid and then to assign to each element an integer between 0 and 9. Forexample, ifsampleBombLocations contains the boolean grid shown earlier, the code
Grid sampleBombCounts;
MakeGridOfCounts(sampleBombLocations, sampleBombCounts);
should initialize sampleBombCounts as follows:
(0,0)
1 1 0 0 2 2
3 3 2 1 4 3
3 3 2 1 3 2
3 4 3 2 2 1
1 2 1 1 0 0
0 1 1 1 0 0
Problem 2. Using queues (Chapter 4, exercise 9, page 170)
Bob Dylans 1963 song The Times They Are A-Changin contains the following lines,which are themselves paraphrased from Matthew 19:30:
And the first one nowWill later be lastFor the times they are a-changin
In keeping with this revolutionary sentiment, write a function
void ReverseQueue(Queue & queue);
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
61/221
2
that reverses the elements in the queue. Remember that you have no access to theinternal representation of the queue and will need to come up with an algorithm,presumably involving other structures, that accomplishes the task.
Problem 3. Using maps (Chapter 4, exercise 14, page 171)
In May of 1844, Samuel F. B. Morse sent the message What hath God wrought! by
telegraph from Washington to Baltimore, heralding the beginning of the age of electroniccommunication. To make it possible to communicate information using only thepresence or absence of a single tone, Morse designed a coding system in which lettersand other symbols are represented as coded sequences of short and long tones,traditionally called dots and dashes. In Morse code, the 26 letters of the alphabet arerepresented by the following codes:
A J S B K TC L U D M V E N W F O X
G P Y H Q Z I R
If you want to convert from letters to Morse code, you could use a switch statement orstore the strings for each letter in a vector with 26 elements; to convert from Morse codeto letters, the easiest approach is to use a map.
Write a program that reads in lines from the user and translates each line either to or fromMorse code depending on the first character of the line:
If the line starts with a letter, you want to translate it to Morse code. Any charactersother than the 26 letters should simply be ignored.
If the line starts with a period (dot) or a hyphen (dash), it should be read as a series of
Morse code characters that you need to translate back to letters. Each sequence ofdots and dashes is separated by spaces, but any other characters should be ignored.
The program should end when the user enters a blank line. A sample run of this program(taken from the messages between the Titanic and the Carpathia in 1912) might look likethis (note that there are no spaces in the Morse-to-letters translation):
Morse code translator
> SOS TITANIC
... --- ... - .. - .- -. .. -.-.
>WE ARE SINKING FAST
.-- . .- .-. . ... .. -. -.- .. -. --. ..-. .- ... -
> .... . .- -.. .. -. --. ..-. --- .-. -.-- --- ..-
HEADINGFORYOU>
Problem 4. Using lexicons (Chapter 4, exercise 15, page 172)
In Chapter 3, exercise 6, you were asked to write a function IsPalindrome that checkswhether a word is a palindrome, which means that it reads identically forward andbackward. Use that function together with the lexicon of English words to print out a listof all words in English that are palindromes.
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
62/221
Eric Roberts Handout #17ACS106B April 13, 2009
Solutions to Section Handout #2
Problem 1. Using grids
/** Function: MakeGridOfCounts* Usage: MakeGridOfCounts(locations, counts);* -------------------------------------------* This function uses the first grid to indicate where mines are* located and creates a second grid showing the count of mines* in the neighborhood of each square.*/
void MakeGridOfCounts(Grid & locations, Grid & counts) {int nRows = locations.numRows();int nCols = locations.numCols();counts.resize(nRows, nCols);
for (int i = 0; i < nRows; i++) {for (int j = 0; j < nCols; j++) {counts[i][j] = CountBombNeighbors(locations, i, j);
}}
}
/** Function: CountBombNeighbors* Usage: int nBombs = CountBombNeighbors(locations, row, col);* ------------------------------------------------------------* Counts the number of bombs in the immediate neighborhood.*/
int CountBombNeighbors(Grid & locations, int row, int col) {int nBombs = 0;for (int i = -1; i = 0 && col < grid.numCols();}
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
63/221
Problem 2. Using queues
/** Reverses the order of elements in a queue using a stack.*/
void ReverseQueue(Queue & queue) {
Stack stack;while (!queue.isEmpty()) {stack.push(queue.dequeue());
}while (!stack.isEmpty()) {
queue.enqueue(stack.pop());}
}
Problem 3. Using maps
This problem was slightly buggy because there is no way to add spaces between thewords when translating from Morse to English. The last lines of the sample run should
look like this:> .... . .- -.. .. -. --. ..-. --- .-. -.-- --- ..-HEADINGFORYOU>
/** File: MorseCode.cpp* ------------------* This program translates to and from Morse Code.* The translation from letters to Morse Code uses an array;* The translation from Morse Code to letters uses a map.*/
#include "genlib.h"#include "simpio.h"#include "map.h"#include "strutils.h"#include
/* Constants */
const string MORSE_CODE[] = {".-" /* A */, "-..." /* B */, "-.-." /* C */,"-.." /* D */, "." /* E */, "..-." /* F */,"--." /* G */, "...." /* H */, ".." /* I */,".---" /* J */, "-.-" /* K */, ".-.." /* L */,
"--" /* M */, "-." /* N */, "---" /* O */,".--." /* P */, "--.-" /* Q */, ".-." /* R */,"..." /* S */, "-" /* T */, "..-" /* U */,"...-" /* V */, ".--" /* W */, "-..-" /* X */,"-.--" /* Y */, "--.." /* Z */
};
/* Function protoypes */
string TranslateLettersToMorse(string line);string TranslateMorseToLetters(string line, Map & morseTable);void CreateMorseCodeTable(Map & morseTable);
http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/http://www.pdfxviewer.com/ -
7/30/2019 stanford handout
64/221
/* Main program */
int main() {cout
-
7/30/2019 stanford handout
65