stanford handout

Upload: srinip007

Post on 04-Apr-2018

223 views

Category:

Documents


0 download

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