recursive methods
play

Recursive Methods Recursive problem solution Problems that are - PDF document

Recursive Methods Recursive problem solution Problems that are naturally solved by recursion Derivative of rational function Recursive Methods Examples: Recursive function: Fibonacci numbers Recursive graphics:


  1. Recursive Methods • Recursive problem solution – Problems that are naturally solved by recursion – Derivative of rational function Recursive Methods • Examples: – Recursive function: Fibonacci numbers – Recursive graphics: Fractals – Mutual recursion: Expression evaluation Noter ch.2 – Randomization and recursion: Random plants/trees • General aspects – Termination – Recursion versus iteration: simplicity vs efficiency Natural Recursion: Recursive Function: Derivative of Rational Function Fibonacci Numbers • The sequence of Fibonacci numbers is • First 10 terms are – 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 Recursive method calls itself Recursive Function: Tree Structure of Method Call fib(4) 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); }

  2. Recursive graphics Fractals: Koch lines of order 1-4 • The snowflake is built • A line of order 0 is a from 3 Koch lines of straight line order 4. • A line of order n • The Koch line is consists of 4 lines of defined recursively order 3 each of 1/3 length Order 0 Order n−1 Order n−1 n>=1 Order n−1 Order n−1 Extending Crayon SnowFlakeCrayon public class SnowflakeCrayon extends Crayon { • Crayon class public SnowflakeCrayon(Color c, double w) { – dIntProg-opgaver 1.2.1 super(c,w); • class SnowFlakeCrayon will inherit all } the Crayon methods, and get one new public void snowflake(int order , int len) { method: kochLine( order ,len); turn(120); kochLine( order ,len); turn(120); public void snowflake(int order, int len) {...} kochLine( order ,len); turn(120); • Application: } SnowflakeCrayon c = new SnowflakeCrayon(Color.red,1); private void kochLine(int order , double len) {...} c.jumpto(50,150); } c.snowflake(4,300); recursive method kochLine Mutual Recursion private void kochLine(int order, double len) { • op and ned are mutually recursive: if (order == 0) move(len); else if (order > 0) { public void ned(int n) { kochLine(order-1,len/3); turn(-60); while(n%2==0) n = n/2; kochLine(order-1,len/3); turn(120); op(n); kochLine(order-1,len/3); turn(-60); } kochLine(order-1,len/3); Order } public void op(int n) { } if (n>1) { n = 3*n+1; ned(n); } 0 } • It is unknown whether the call ned(m) terminates for all m ! Order n−1 Order n−1 n>=1 Order n−1 Order n−1

  3. Using Mutual Recursion Syntax diagram for expression • Problem: – compute the value of arithmetic expressions such as 3 + 4 * 5 (3 + 4) * 5 1 – (2 – (3 – (4 – 5))) • Precedence rules: – * and / take precedence over + and – – may overrule using parentheses ( ... ) number Syntax tree for two expressions Mutually recursive methods • Implement 3 methods that call each other recursively getExpressionValue getTermValue getFactorValue • An ExpressionTokenizer is used to group input in tokens. A token being a string of digits or one of "+", "-", "*", "/", "(", ")". Methods: peekToken nextToken public class Evaluator { public int getExpressionValue () { int value = getTermValue (); public Evaluator(String anExpression) { boolean done = false; tokenizer = new ExpressionTokenizer(anExpression); while (!done) { } String next = tokenizer.peekToken(); if ("+".equals(next) || "-".equals(next)) { public int getExpressionValue() { ... } tokenizer.nextToken(); int value2 = getTermValue (); public int getTermValue() { ... } if ("+".equals(next)) value = value + value2; else value = value - value2; public int getFactorValue() { ... } } else done = true; } return value; private ExpressionTokenizer tokenizer; } }

  4. public int getTermValue () { public int getFactorValue () { int value = getFactorValue (); int value; boolean done = false; String next = tokenizer.peekToken(); while (!done) { if ("(".equals(next)) { String next = tokenizer.peekToken(); if ("*".equals(next) || "/".equals(next)) { tokenizer.nextToken(); tokenizer.nextToken(); value = getExpressionValue (); int value2 = getFactorValue (); next = tokenizer.nextToken(); //read ")" if ("*".equals(next)) value = value * value2; } else value = else value = value / value2; Integer.parseInt(tokenizer.nextToken()); } else done = true; } return value; return value; } } Random trees and flowers Random trees and flowers Recursive trees Variation by randomization Order n−1 BRANCH_ANGLE 3 smaller trees/branches Order n−1 Order n−1 = leaf trunk Tree trunk Order 0 n>=1 • leaf, branch, trunk differ by colors and thickness • 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 leaf/branch/trunk • Subtrees are tilted with angle to neighbor being BRANCH_ANGLE=13 deg. Order 0 1 2 3 4 5 6

  5. Extending CCrayon class TreeCrayon import java.awt.*; • CCrayon is a variant of Crayon with 2 extra public class TreeCrayon extends CCrayon { methods: setColor , setWidth /** tree draws a random tree * @param order - order of tree • class TreeCrayon will inherit all the CCrayon * @param len - length of trunk */ methods, and get one new public method: public void tree(int order, int len) {...} public void tree(int order, int len) {...} /** leaf draws maybe(!) a leaf of a random color • Application: * @param len - side length of leaf */ TreeCrayon c = new TreeCrayon(); private void leaf(int len) { ... } c.jumpto(200,400); private final static int BRANCH_MAX = 6; c.turn(-90); private final static int BRANCH_ANGLE = 13; c.tree(6,40); private final static double BRANCH_PROB = 0.4; private final static double LEAF_PROB = 0.3; } Recursive method tree Method leaf public void tree (int order, int len) { private void leaf(int len) { if (order==0) leaf (len/2); if (Math.random()<LEAF_PROB) { else { if (Math.random()<0.5) setColor(Color.red); int bias = (int) (2*Math.random()); if (order+bias >=6) setColor(Color.black); else setColor(Color.yellow); else if (order+bias >=4) setColor(Color.gray); setWidth(2); else setColor(Color.green); turn(-BRANCH_ANGLE/2.0); move(len); setWidth(2*order); move(len); turn(BRANCH_ANGLE); move(len); turn((BRANCH_ANGLE*(BRANCH_MAX-1))/2.0); turn(180-BRANCH_ANGLE); move(len); for (int i = 1 ; i<=BRANCH_MAX ; i = i+1 ) { turn(BRANCH_ANGLE); move(len); if (Math.random()<BRANCH_PROB) tree (order-1, len-2); turn(180-BRANCH_ANGLE/2.0); turn(-BRANCH_ANGLE); } } } turn((BRANCH_ANGLE*(BRANCH_MAX+1))/2.0); turn(180); jump(len); turn(-180); //return pen to base of tree } } Recursion in general: Termination Thinking recursively vs efficiency • Recursive solution may be natural and simple to program • Recursive call need not terminate public long fib(int n) { public void loopingRecursiveMethod() { if (n <= 1) return 1; loopingRecursiveMethod(); else return fib(n - 1) + fib(n - 2); } } • Any reasonable recursive method should have recursion • But iterative solution may be more efficient public long iterativeFib(int n) { condition if (n <= 1) return 1; long fold = 1; public long fib(int n) { long fold2 = 1; no recursive call if (n <= 1) return 1; long fnew = 1; else return fib(n - 1) + fib(n - 2); for (int i = 2; i <= n; i++) { } fnew = fold + fold2; recursive call fold2 = fold; private void kochLine(int order, double len) { fold = fnew; if (order == 0) no recursive call } else if (order > 0) recursive call return fnew; } }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend