recursive methods noter ch.2. quiz what is the result of the method call foo(4) ? 1.prints 4...

40
Recursive Methods Noter ch.2

Upload: lindsey-mills

Post on 11-Jan-2016

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive Methods

Noter ch.2

Page 2: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

What is the result of the method call foo(4) ?

1. Prints 4

2. Prints 1

3. Prints 1 2 3 4

4. Prints 4 3 2 1

5. Compiler error: method foo is not allowed to call itself

6. Runtime error: method foo is not allowed to call itself

7. I don’t know

public static void foo(int x) {

System.out.println(x);

if (x>1)

foo(x-1);

}

Page 3: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive Methods

• Recursive problem solution– Problems that are naturally solved by recursion– Derivative of rational function

• Examples:– Recursive function: Fibonacci numbers– Recursive graphics: Fractals– Mutual recursion: Expression evaluation– Randomization and recursion: Random plants/trees

• General aspects– Termination– Recursion versus iteration: simplicity vs efficiency

Page 4: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Natural Recursion:Derivative of Rational Function

Recursive method calls itself

Page 5: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZWhat is the proper recursive definition of the factorial function?

1. n! = n * (n-1)!

2. n! =

3. n! =

4. n! =

5. n! =

6. I don’t know

Factorial function:

n! = 1 * 2 * 3 * ... * (n-1) * n

(n-1)! For n > 11 For n = 1

(n-1)! For n > 1n-1 For n = 1

n*(n-1)! For n > 11 For n = 1

n*(n-1) For n > 1(n-1)! For n = 1

Page 6: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

What is the proper method header?

1.public static void factorial()

2.public static int factorial()

3.public static void factorial(int n)

4.public static int factorial(int n)

5. I don’t know

Factorial function:

n! = 1 * 2 * 3 * ... * (n-1) * n

Java method for computing factorial function:

<method header> {

<base case>

<recursive case>

}

Page 7: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

What is the proper base case?

1.return 1;

2.return factorial(1);

3.if (n==1) return 1;

4.if (n==1) return factorial(1);

5.return n-1;

6.return factorial(n-1);

7.if (n==1) return n-1;

8.if (n==1) return factorial(n-1);

9. I don’t know

Factorial function:

n! = 1 * 2 * 3 * ... * (n-1) * n

Java method for computing factorial function:

<method header> {

<base case>

<recursive case>

}

Page 8: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

What is the proper recursive case?

1.factorial(n-1);

2.factorial(n*n-1);

3.n*factorial(n-1);

4.return factorial(n-1);

5.return factorial(n*n-1);

6.return n*factorial(n-1);

7. I don’t know

Factorial function:

n! = 1 * 2 * 3 * ... * (n-1) * n

Java method for computing factorial function:

<method header>{

<base case>

<recursive case>

}

Page 9: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive Function:Fibonacci Numbers

• The sequence of Fibonacci numbers is

• First 10 terms are – 1, 1, 2, 3, 5, 8, 13, 21, 34, 55

Page 10: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive Function:Fibonacci Numbers

• Recursive method corresponding to recursive definition of Fibonacci numbers

public long fib(int n) { if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);}

Page 11: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Tree Structure of Method Call fib(4)

Page 12: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

Which lines should replace to

obtain a correct and recursive

computation of triangle area ?

(for n=4, the area is 10)

1. None of a,b,c,d

2. a

3. b

4. c

5. d

6. More than one of a,b,c,d could be used

7. I don’t know

/* @precondition n>=1 */

public int area(int n) { }

a) return n*(n+1)/2;

b) if (n==1) return 1; else return area(n-1);

c) return n+area(n-1);

d) if (n==1) return 1; else return n+area(n-1);

n

Page 13: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive graphics

• The snowflake is built from 3 Koch lines of order 4.

• The Koch line is defined recursively

Page 14: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Fractals: Koch lines of order 1-4

• A line of order 0 is a straight line

• A line of order n consists of 4 lines of order n-1 each of 1/3 length

Page 15: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Crayon class• State of Crayon object

– Colour– Width (pixel)– Position (coordinates)– Direction (0-360 deg)

• Public methods– Relative changes– move(d): draw line of lenght d (from position in direction to new position)– jump(d): change position without drawing– turn(a): add a degrees to direction– Absolute changes– moveto(x,y):– jumpto(x,y): – turnto(a):

Page 16: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

KochLineTest

public class KochLineTest {

public static void main(String[] args) { c = new Crayon(Color.red,1); c.jumpto(50,150); kochLine(4,300); c.turn(120); kochLine(4,300); c.turn(120); kochLine(4,300); c.turn(120); }

private static Crayon c;

private static void kochLine(int order, double len) {...}

}

Page 17: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

recursive method kochLine

void kochLine(int order, double len) {

if (order == 0) c.move(len);

else if (order > 0) {

kochLine(order-1,len/3); c.turn(-60);

kochLine(order-1,len/3); c.turn(120);

kochLine(order-1,len/3); c.turn(-60);

kochLine(order-1,len/3);

}

}

Page 18: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

Which figures may be

drawn using the method?

1. neither

2. a

3. b

4. a+b

5. I don’t know

private void line(int order, double len, int sign) {

if (order == 0) c.move(len);

else if (order > 0) {

c.turn(sign*60);

line(order-1,len/2,-sign); c.turn(-sign*60);

line(order-1,len/2,sign); c.turn(-sign*60);

line(order-1,len/2,-sign); c.turn(sign*60);

} }a b

Page 19: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Mutual Recursion

• up and down are mutually recursive:

public void down(int n) {

while(n%2==0) n = n/2;

up(n);

}

public void up(int n) {

if (n>1) { n = 3*n+1; down(n); }

}

• It is unknown whether the call down(m) terminates for all m!

Page 20: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

Which assertions are correct?

1. Both odd and even always stops

2. odd always stops, but even may loop indefinitely

3. even always stops, but odd may loop indefinitely

4. Both odd and even may loop indefinitely

5. I don’t know

Precondition for both methods: n >= 0

public boolean even(int n) {

if (n==0) return true;

return odd(n-1);

}

public boolean odd(int n) {

if (n==0) return false;

return even(n-1);

}

Page 21: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Using Mutual Recursion

• Problem:– compute the value of arithmetic expressions

such as3 + 4 * 5

(3 + 4) * 51 – (2 – (3 – (4 – 5)))

• Precedence rules: – * and / take precedence over + and –– may overrule using parentheses ( ... )

Page 22: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Syntax diagram for expression

number

Page 23: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Syntax tree for two expressions

Page 24: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Mutually recursive methods

• Implement 3 methods that call each other recursivelygetExpressionValue

getTermValue

getFactorValue

• An ExpressionTokenizer is used to group input in tokens. A token being a string of digits or one of "+", "-", "*", "/", "(", ")". Methods:peekToken

nextToken

Page 25: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

public class Evaluator { public Evaluator(String anExpression) { tokenizer = new ExpressionTokenizer(anExpression); }

public int getExpressionValue() { ... }

public int getTermValue() { ... }

public int getFactorValue() { ... }

private ExpressionTokenizer tokenizer;}

Page 26: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

public int getExpressionValue() { int value = getTermValue(); while ("+".equals(tokenizer.peekToken()) || "-".equals(tokenizer.peekToken())) { String operator = tokenizer.nextToken(); int value2 = getTermValue(); if ("+".equals(operator)) value = value + value2; else value = value - value2; } return value;}

Page 27: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

public int getTermValue() { int value = getFactorValue(); while ("*".equals(tokenizer.peekToken()) || "/".equals(tokenizer.peekToken())) { String operator = tokenizer.nextToken(); int value2 = getFactorValue(); if ("*".equals(operator)) value = value * value2; else value = value / value2; } return value;}

Page 28: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

public int getFactorValue() { int value; if ("(".equals(tokenizer.peekToken())) { tokenizer.nextToken(); value = getExpressionValue(); tokenizer.nextToken(); // read ")" } else value = Integer.parseInt(tokenizer.nextToken()); return value;}

Page 29: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

Which code could

replace ?

1. Neither a nor b

2. a

3. b

4. a or b

5. I don’t know

public boolean getTermValue() { }

if ("!".equals(tokenizer.peekToken())) { tokenizer.nextToken(); return !getFactorValue();}return getFactorValue();

boolean value = getFactorValue();if ("!".equals(tokenizer.peekToken())) { tokenizer.nextToken(); value = !value;}return value;

a

b

(Part of) syntax diagram for Boolean expression

Page 30: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Random trees and flowers

Page 31: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Random trees and flowers

Page 32: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive trees

• leaf, branch, trunk differ by colors and thickness

Page 33: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Variation by randomization

• Each tree consists of a trunk and up to BRANCH_MAX=6 smaller trees

• Each of the subtrees are drawn with probability BRANCH_PROB=0.4

• Subtrees are tilted with angle to neighbor being BRANCH_ANGLE=13 deg.

Page 34: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

class CCrayon

•CCrayon is a variant of Crayon with 2 extra methods:– setColor– setWidth

Page 35: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

class TreeTestpublic class TreeTest {

public static void main(String[] args) { c = new CCrayon(); c.jumpto(200,400); c.turn(-90); tree(6,40); } private static CCrayon c;

private static void tree(int order, int len) {...}

private static void leaf(int len) { ... }

private final static int BRANCH_MAX = 6; private final static int BRANCH_ANGLE = 13; private final static double BRANCH_PROB = 0.4; private final static double LEAF_PROB = 0.3;}

Page 36: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursive method treepublic void tree(int order, int len) { if (order==0) leaf(len/2); else { int bias = (int) (2*Math.random()); if (order+bias >=6) c.setColor(Color.black); else if (order+bias >=4) c.setColor(Color.gray); else c.setColor(Color.green); c.setWidth(2*order); c.move(len); c.turn((BRANCH_ANGLE*(BRANCH_MAX-1))/2.0); for (int i = 1 ; i<=BRANCH_MAX ; i = i+1 ) { if (Math.random()<BRANCH_PROB) tree(order-1, len-2); c.turn(-BRANCH_ANGLE); } c.turn((BRANCH_ANGLE*(BRANCH_MAX+1))/2.0); c.turn(180); c.jump(len); c.turn(-180); //return pen to base of tree }}

Page 37: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Method leafvoid leaf(int len) { if (Math.random()<LEAF_PROB) { if (Math.random()<0.5) c.setColor(Color.red); else c.setColor(Color.yellow); c.setWidth(2); c.turn(-BRANCH_ANGLE/2.0); c.move(len); c.turn(BRANCH_ANGLE); c.move(len); c.turn(180-BRANCH_ANGLE); c.move(len); c.turn(BRANCH_ANGLE); c.move(len); c.turn(180-BRANCH_ANGLE/2.0); } }

Page 38: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Recursion in general: Termination

• Recursive call need not terminatepublic void loopingRecursiveMethod() { loopingRecursiveMethod();}

• Any reasonable recursive method should have recursion condition

public long fib(int n) { if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);}

private void kochLine(int order, double len) { if (order == 0) no recursive call else if (order > 0) recursive call}

no recursive call

recursive call

Page 39: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

Thinking recursively vs efficiency• Recursive solution may be natural and simple to program

public long fib(int n) { if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);}

• But iterative solution may be more efficientpublic long iterativeFib(int n) { if (n <= 1) return 1; long fold = 1; long fold2 = 1; long fnew = 1; for (int i = 2; i <= n; i++) { fnew = fold + fold2; fold2 = fold; fold = fnew; } return fnew;}

Page 40: Recursive Methods Noter ch.2. QUIZ What is the result of the method call foo(4) ? 1.Prints 4 2.Prints 1 3.Prints 1 2 3 4 4.Prints 4 3 2 1 5.Compiler error:

QUIZ

How many recursive calls result

in total from the call bin(n,k)

(approximate number)?

1. n

2.

3. n+k

4. nk

5.

6. I don’t know

/* @precondition 0<=k<=n */

public int bin(int n, int k) {

if (k==0 || k==n) return 1;

return bin(n-1,k-1)

+ bin(n-1,k);

}

k=0 k=1 k=2 k=3 k=4 k=5 k=6

n=1 1 1

n=2 1 2 1

n=3 1 3 3 1

n=4 1 4 6 4 1

n=5 1 5 10 10 5 1

n=6 1 6 15 20 15 6 1

k

n

k

n

n2