310 likes | 338 Vues
Midterm Review. Eric Roberts CS 106A February 7, 2010. Karel—Practice #1. Karel Plays Breakout. /* * File: BreakoutKarel.java * ------------------------ * The BreakoutKarel class solves the Karel problem from the * first practice midterm exam. */ import stanford.karel.*;
E N D
Midterm Review Eric Roberts CS 106A February 7, 2010
Karel Plays Breakout /* * File: BreakoutKarel.java * ------------------------ * The BreakoutKarel class solves the Karel problem from the * first practice midterm exam. */ import stanford.karel.*; public class BreakoutKarel extends SuperKarel { public void run() { while (beepersInBag()) { if (beepersPresent()) { pickBeeper(); bounce(); } while (frontIsBlocked()) { bounce(); } stepDiagonally(); } } page 1 of 2
/* * Causes Karel to perform a ricochet bounce, which requires * no more than turning left. */ private void bounce() { turnLeft(); } /* * Step diagonally. The precondition for this call is that * Karel's front must be clear. The postcondition has Karel * facing in the same direction. */ private void stepDiagonally() { move(); if (leftIsClear() && noBeepersPresent()) { turnLeft(); move(); turnRight(); } } } Karel Plays Breakout /* * File: BreakoutKarel.java * ------------------------ * The BreakoutKarel class solves the Karel problem from the * first practice midterm exam. */ import stanford.karel.*; public class BreakoutKarel extends SuperKarel { public void run() { while (beepersInBag()) { if (beepersPresent()) { pickBeeper(); bounce(); } while (frontIsBlocked()) { bounce(); } stepDiagonally(); } } page 2 of 2
Valentine Karel import stanford.karel.*; public class ValentineKarel extends SuperKarel { /* Runs the program */ public void run() { for (int i = 0; i < 4; i++) { moveUp2Rows(); deliverValentinesToOneRow(); returnToStartOfRow(); } } /* * Moves Karel to the same column, two rows above where * it currently is. The precondition and postcondition * both have Karel facing east. */ private void moveUp2Rows() { turnLeft(); move(); move(); turnRight(); } page 1 of 2
/* * Returns Karel to the beginning of the row on which it * begins. The precondition and postcondition both * have Karel facing east. */ private void returnToStartOfRow() { turnAround(); moveToWall(); turnAround(); } /* * Drives Karel along the row, placing beepers whenever * there is a "desk" to the right, signified by a wall. * The precondition is that Karel must be facing east * at the beginning of a row. The postcondition is that * Karel will be in the same location after having * delivered all the valentines. */ private void deliverValentinesToOneRow() { while (frontIsClear()) { move(); if (rightIsBlocked()) { putBeeper(); } } } Valentine Karel import stanford.karel.*; public class ValentineKarel extends SuperKarel { /* Runs the program */ public void run() { for (int i = 0; i < 4; i++) { moveUp2Rows(); deliverValentinesToOneRow(); returnToStartOfRow(); } } /* * Moves Karel to the same column, two rows above where * it currently is. The precondition and postcondition * both have Karel facing east. */ private void moveUp2Rows() { turnLeft(); move(); move(); turnRight(); } page 2 of 2
1.25 Both of these operands are integers so the result is truncated to an int. 1.25 0 Because the left operand of the && operator is false, Java does not evaluate the right operand, thereby avoiding the division-by-zero error. false false 4 This generates an error because subtraction is undefined for strings. "B84" "B8" "E" - "A" Expression Tracing 5.0 / 4 - 4 / 5 7 < 9 - 5 && 3 % 0 == 3 "B" + 8 + 4
7 5 4 3 2 1 0 9 8 7 5 4 6 "cabbag" "cabba" "cabb" "" "c" "cabbage" "ca" "cab" "abcdefg" Algorithmic Tracing—Practice #1 private String mystery(String s) { String result = ""; int len = s.length(); int j = 0; int k = 9; while (j < k) { if (j < 4) { result += s.charAt(k % len); } if (j / 2 != 1) { result += s.charAt(j % len); } j++; k--; } return result; } len j k result str
19 0 1729 0 9 172 11 17 18 1 0 1 0 9 1 10 0 10 0 1 1 19 Algorithmic Tracing—Practice #2 private int mystery(int n) { while (n >= 10) { int k = 0; while (n > 0) { k += n % 10; n /= 10; } n = k; } return n; } k n
private String forgive(String me, String you) { String heart = me.substring(0, you.length() - me.length()); you = "" + you.charAt(me.length()); int amount = heart.length(); me = me.substring(amount + 2) + me.charAt(amount); heart += understanding(you, 2) + you + me; return heart; } private char understanding(String you, int num) { return (char)(you.charAt(0) + num); } "To care" amount heart me you you num "To err" "is human!" "a" "To " "To care" "re" "a" 2 Method Tracing—Practice #1 public void run() { String s1 = "To err"; String s2 = "is human!"; s1 = forgive(s1, s2); println(s1 + " " + s2); } 'c' s2 s1 "is human!" "To err" 3 Problem2c To care is human!
private String valentine(String s1, String s2) { int num = (s1.substring(1, 2)).length(); s1 = s2.substring(num); s2 = cupid(s1, s2.charAt(0)); return (s2); } private String cupid(String s1, char ch) { return (s1 + Character.toLowerCase(ch)); } s2 num s1 s1 ch "earth" "eart" "Heart" "candy" 'H' "eart" Method Tracing—Practice #2 public void run() { String s1 = "Heart"; String s2 = valentine("candy", s1); println("s1 = " + s1); println("s2 = " + s2); } s2 s1 "earth" "Heart" 1 Problem2c s1 = Heart s2 = earth
Problem 3—Practice #1 In Assignment #2, you wrote a program to find the largest and smallest integers in a list entered by the user. For this problem, write a similar program that instead finds the largest and the second-largest integer. As in the homework problem, you should use 0 as a sentinel to indicate the end of the input list. Thus, a sample run of the program might look like this: FindTwoLargest This program finds the two largest integers in a list. Enter values, one per line, using a 0 to signal the end of the list. ? 17 ? 42 ? 11 ? 19 ? 35 ? 0 The largest value is 42 The second largest value is 35
public void run() { println("This program finds the two largest integers in a"); println("list. Enter values, one per line, using a " + SENTINEL + " to"); println("signal the end of the list."); int largest = -1; int secondLargest = -1; while (true) { int input = readInt(" ? "); if (input == SENTINEL) break; if (input > largest) { secondLargest = largest; largest = input; } else if (input > secondLargest) { secondLargest = input; } } println("The largest value is " + largest); println("The second largest is " + secondLargest); } This code handles the case when the input value is larger than any value yet seen. It then becomes the largest, and the old maximum is now the second largest. It is also necessary to check for the case in which the new value is larger than the previous candidate for second-largest, even if it isn’t the largest so far. Finding the Two Largest Values
Problem 3—Practice #2 As you undoubtedly learned in school, the Pythagorean Theorem holds that the length of the hypotenuse (z) of a right triangle with sides x and y is given by the following formula: x2 + y2 = z2 Write a Java program that prints out all Pythagorean triples in which both x and y are less than or equal to a named constant LIMIT and x is less than y For example, if LIMIT is 25, your program should generate the following sample run:: PythagoreanTriples 3, 4, 6 5, 12, 13 6, 8, 10 7, 24, 25 8, 15, 17 9, 12, 15 10, 24, 26 12, 16, 20 15, 20, 25 18, 24, 30 20, 21, 29
import acm.program.*; import acm.graphics.*; public class PythagoreanTriples extends ConsoleProgram { public void run() { for (int a = 1; a <= LIMIT; a++) { for (int b = a; b <= LIMIT; b++) { int csq = a * a + b * b; int c = GMath.round(Math.sqrt(csq)); if (c * c == csq) { println(a + ", " + b + ", " + c); } } } } /* Maximum value for a and b */ private static final int LIMIT = 25; } Finding Pythagorean Triples
Problem 4—Practice #1 Write a GraphicsProgram that does the following: 1. Creates the following cross as a GCompound containing two filled rectangles: 2. Adds the cross to the canvas so that it appears at the center of the window. 3. Moves the cross at a speed of 3 pixels every 20 milliseconds in a random direction, which is specified as a random real number between 0 and 360 degrees. 4. Every time you click the mouse inside the cross, its direction changes to some new random direction; its velocity remains the same. Clicks outside the cross have no effect.
Red Cross /* * File: RandomlyMovingRedCross.java * --------------------------------- * This program solves the practice midterm problem. */ import acm.program.*; import acm.util.*; import java.awt.event.*; public class RandomlyMovingRedCross extends GraphicsProgram { /* Sets up the program at the beginning */ public void init() { cross = new RedCross(); add(cross, getWidth() / 2, getHeight() / 2); chooseRandomDirection(); addMouseListeners(); } page 1 of 4
/* Runs the simulation */ public void run() { while (true) { cross.movePolar(VELOCITY, direction); pause(PAUSE_TIME); } } /* Called when the mouse is clicked */ public void mouseClicked(MouseEvent e) { if (cross.contains(e.getX(), e.getY())) { chooseRandomDirection(); } } /* Resets the direction to a random value */ private void chooseRandomDirection() { direction = rgen.nextDouble(0, 360); } Red Cross /* * File: RandomlyMovingRedCross.java * --------------------------------- * This program solves the practice midterm problem. */ import acm.program.*; import acm.util.*; import java.awt.event.*; public class RandomlyMovingRedCross extends GraphicsProgram { /* Sets up the program at the beginning */ public void init() { cross = new RedCross(); add(cross, getWidth() / 2, getHeight() / 2); chooseRandomDirection(); addMouseListeners(); } page 2 of 4
/* Private constants */ private static final double PAUSE_TIME = 20; private static final double VELOCITY = 2; /* Private instance variables */ private RedCross cross; private double direction; private RandomGenerator rgen = RandomGenerator.getInstance(); } Red Cross /* Runs the simulation */ public void run() { while (true) { cross.movePolar(VELOCITY, direction); pause(PAUSE_TIME); } } /* Called when the mouse is clicked */ public void mouseClicked(MouseEvent e) { if (cross.contains(e.getX(), e.getY())) { chooseRandomDirection(); } } /* Resets the direction to a random value */ private void chooseRandomDirection() { direction = rgen.nextDouble(0, 360); } page 3 of 4
/* * File: RedCross.java * ------------------- * This class defines a red cross whose size is specified * by the constants CROSSBAR_LENGTH and CROSSBAR_WIDTH. */ import acm.graphics.*; import java.awt.*; public class RedCross extends GCompound { /* Constructs a red cross centered at the origin */ public RedCross() { GRect hCrossbar = new GRect(CROSSBAR_LENGTH, CROSSBAR_WIDTH); GRect vCrossbar = new GRect(CROSSBAR_WIDTH, CROSSBAR_LENGTH); hCrossbar.setFilled(true); vCrossbar.setFilled(true); add(hCrossbar, -CROSSBAR_LENGTH / 2, -CROSSBAR_WIDTH / 2); add(vCrossbar, -CROSSBAR_WIDTH / 2, -CROSSBAR_LENGTH / 2); setColor(Color.RED); } private static final double CROSSBAR_LENGTH = 60; private static final double CROSSBAR_WIDTH = 20; } Red Cross page 4 of 4
Problem 4—Practice #2 As you may recall, the winner in the aesthetic division of this year’s Karel Contest played the game of Frogger . . . Your first task in this problem is to place the frog at the bottom of the graphics window. The frog itself is the easy part because all you need to do is create a GImage object with the appropriate picture, as follows: GImage frog = new GImage("frog.gif"); The harder part is getting the image in the appropriate place in the bottom of the window. In Frogger, the frog image cannot be just anywhere on the screen but must instead occupy a position in an imaginary grid. . . . The second part of the problem is getting the frog to jump when the user clicks the mouse. The goal is to get the frog to jump one square in the direction that moves it closest to the mouse. . . .
Frogger /* * File: SimpleFrogger.java * ------------------------ * This program solves the Frogger problem from the practice midterm. */ import acm.graphics.*; import acm.program.*; import java.awt.*; import java.awt.event.*; /* * This program gets a frog to jump one square in the closest * direction to a mouse click. */ public class SimpleFrogger extends GraphicsProgram { public void run() { frog = new GImage("frog.gif"); fx = (NCOLUMNS / 2 + 0.5) * SQUARE_SIZE; fy = (NROWS - 0.5) * SQUARE_SIZE; add(frog, fx - frog.getWidth() / 2, fy - frog.getHeight() / 2); addMouseListeners(); } page 1 of 4
/* Responds to a mouse click */ public void mouseClicked(MouseEvent e) { double mx = e.getX(); double my = e.getY(); if (Math.abs(mx - fx) > Math.abs(my - fy)) { if (mx > fx) { moveFrog(SQUARE_SIZE, 0); } else { moveFrog(-SQUARE_SIZE, 0); } } else { if (my > fy) { moveFrog(0, SQUARE_SIZE); } else { moveFrog(0, -SQUARE_SIZE); } } } Frogger /* * File: SimpleFrogger.java * ------------------------ * This program solves the Frogger problem from the practice midterm. */ import acm.graphics.*; import acm.program.*; import java.awt.*; import java.awt.event.*; /* * This program gets a frog to jump one square in the closest * direction to a mouse click. */ public class SimpleFrogger extends GraphicsProgram { public void run() { frog = new GImage("frog.gif"); fx = (NCOLUMNS / 2 + 0.5) * SQUARE_SIZE; fy = (NROWS - 0.5) * SQUARE_SIZE; add(frog, fx - frog.getWidth() / 2, fy - frog.getHeight() / 2); addMouseListeners(); } page 2 of 4
/* Moves the frog by dx/dy as long as it remains inside the world */ private void moveFrog(double dx, double dy) { if (insideFroggerWorld(fx + dx, fy + dy)) { fx += dx; fy += dy; frog.move(dx, dy); } } /* Returns true if the point (x, y) is inside the frog's world */ private boolean insideFroggerWorld(double x, double y) { return (x >= 0 && x <= NCOLUMNS * SQUARE_SIZE && y >= 0 && y <= NROWS * SQUARE_SIZE); } Frogger /* Responds to a mouse click */ public void mouseClicked(MouseEvent e) { double mx = e.getX(); double my = e.getY(); if (Math.abs(mx - fx) > Math.abs(my - fy)) { if (mx > fx) { moveFrog(SQUARE_SIZE, 0); } else { moveFrog(-SQUARE_SIZE, 0); } } else { if (my > fy) { moveFrog(0, SQUARE_SIZE); } else { moveFrog(0, -SQUARE_SIZE); } } } page 3 of 4
/* Private constants */ private static final int SQUARE_SIZE = 75; private static final int NROWS = 4; private static final int NCOLUMNS = 7; /* Private instance variables */ private GImage frog; /* The image of the frog */ private double fx; /* The x-coordinate of the frog's center */ private double fy; /* The y-coordinate of the frog's center */ /* Sets the graphics window size */ public static final int APPLICATION_WIDTH = NCOLUMNS * SQUARE_SIZE; public static final int APPLICATION_HEIGHT = NROWS * SQUARE_SIZE; } Frogger /* Moves the frog by dx/dy as long as it remains inside the world */ private void moveFrog(double dx, double dy) { if (insideFroggerWorld(fx + dx, fy + dy)) { fx += dx; fy += dy; frog.move(dx, dy); } } /* Returns true if the point (x, y) is inside the frog's world */ private boolean insideFroggerWorld(double x, double y) { return (x >= 0 && x <= NCOLUMNS * SQUARE_SIZE && y >= 0 && y <= NROWS * SQUARE_SIZE); } page 4 of 4
Problem 5—Practice #1 Write a method removeDoubledLetters that takes a string as its argument and returns a new string with all doubled letters in the string replaced by a single letter. For example, if you call removeDoubledLetters("tresidder") your method should return the string "tresider". Similarly, if you call removeDoubledLetters("bookkeeper") your method should return "bokeper".
/* * Removes any doubled letters from a string. */ private String removeDoubledLetters(String str) { String result = ""; for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); if (i == 0 || ch != str.charAt(i - 1)) { result += ch; } } return result; } Remove Doubled Letters
Problem 5—Practice #2 Write a method removeDoubledLetters that takes a string as its argument and returns a new string with all doubled letters in the string replaced by a single letter. For example, if you call private int countLove(String str) that takes a string as its argument and returns the number of times the word love appears in that string, ignoring differences in case, but making sure that love is not just part of a longer word like clover,glove, pullover, or slovenly. For example, if you were to call countLove("Love in the clover.") your method should return 1. The word Love counts as a match because your method should ignore the fact that Love starts with an uppercase L. The word clover doesn’t match because the letters love are merely part of a larger word.
/* Counts the occurrences of the word "love" in a string */ private int countLove(String str) { String lowerCaseString = str.toLowerCase(); int count = 0; int start = lowerCaseString.indexOf("love"); while (start != -1) { if (isSeparator(lowerCaseString, start - 1) && isSeparator(lowerCaseString, start + 4)) { count++; } start = lowerCaseString.indexOf("love", start + 4); } return count; } /* Checks to see if the ith char of str is a separator */ private boolean isSeparator(String str, int i) { if (i < 0 || i >= str.length()) return true; return !Character.isLetter(str.charAt(i)); } Count Love