220 likes | 332 Views
유환조 Hwanjo Yu. CSED101 INTRODUCTION TO COMPUTING RECURSIVE FUNCTION ( 자기호출함수 ). Review: Local variable. let <variable1> = <expression1> in let <variable2> = <expression2> in … let <variable3> = <expression3> in <final expression> Try in OCAML let x = 1+1 in let y = 2 in x + y;;.
E N D
유환조 Hwanjo Yu CSED101 INTRODUCTION TO COMPUTINGRECURSIVE FUNCTION (자기호출함수)
Review: Local variable • let<variable1> = <expression1> in • let<variable2> = <expression2> in • … • let<variable3> = <expression3> in • <final expression> • Try in OCAML • let x = 1+1 in • let y = 2 in • x + y;;
Review: Local variable • let<variable1> = let <variable2> = <expression2> in <final expression2> in <final expression1>;; • What would be the value of x in “let x = let y = 1 + 1 in y + y in x + x” ? • Too complicated? Let’s rewrite it into… • let x = • let y = • 1+1 • in y+y • in x+x”? • => 8
Review: Function • let <name> = fun <arg1><arg2> .. -> <body>;; • let <name> <arg1> <arg2> .. = <body>;; • let f = fun a -> • let g = fun x -> a*x • in (g 1) + (g 2);; • let f a = • let g x = • a * x • in (g 1) + (g 2);; • f 1;; • f 2;;
Review: Tuple • Tuple to return multiple values in a function • let h x y = (x+y, x*y);; • Tuple as function arguments • let f (x, y) (v, w) = x*v + y*w;; • let f a b = • let (x, y) = a in • let (v, w) = b in • x*v + y*w;;
Review: cmp a b • let cmp a b = • let _ = print_string “integer a = “ in • let _ = print_int a in • let _ = print_newline () in • let _ = print_string “integer b = “ in • let _ = print_int b in • let _ = print_newline () in • let msg = • if a > b then “a is greater than b” • else if b > a then “b is greater than a” • else “a and b are equal” • in print_string msg;;
Review: Recursive function • Define a function “sum” that does the following • Sum type: int -> int • Assume n >= 1 • Return the sum of 1 to n • let rec sum n = • if n = 1 then 1 • else sum (n-1) + n;;
Review: Recursive function • The body of a recursive function consists of three components • if <termination condition> then <base case> else <recursive case> • Or, • if not <termination condition> then <recursive case> else <base case> • E.g., • if n = 1 then 1 else sum (n-1) + n • Or • if n > 1 then sum (n-1) + n else 1
Review: Recursive function • There must be a <termination condition>, otherwise infinite loop! • let rec sum n = sum (n-1) + n;; • The argument value must change, otherwise infinite loop! • let rec sum n = • if n=1 then 1 else sum n + n;;
Exercise: sum_even n • Write a recursive function “sum_even n” that does the following • n, an argument, is an even number. • If n is an odd or negative number, then print “argument error..” and return -1 • “sum_even n” computes the sum of even numbers up to n, i.e., 2, 4, 6,… , n
Exercise: sum_even n • let rec sum_even n = • if n < 0 || n mod 2 <> 0 then • let _ = print_string “argument error..” in -1 • else if n = 0 then 0 • else sum_even (n-2) + n;;
Recursive function that calls itself multiple times • Recursive function can call itself multiple times within the function • E.g., Fibonacci sequence (피보나치 수열) • 1, 1, 2, 3, 5, 8, 13, 21, … • Fn = Fn-1 + Fn-2 • F2 = F1 = 1
Recursive function for Fibonacci sequence • Input and output type: int - > int • Argument is assumed to be >= 1 • fib n returns Fn in the fibonacci sequence • let rec fib n = • if n > 2 then fib (n-1) + fib (n-2) • else 1;;
Recursive function for Fibonacci sequence • let rec fib n = • if n > 2 then fib (n-1) + fib (n-2) • else 1;; • Fib calls itself twice - fib (n-1) and fib (n-2), but the arguments will be decreased by one or two each time it is called, thus No infinite loop!
Recursive function with unchanging argument • Consider the following sequence • a1 = 1 • an = k an-1 + 1 • Type of f: int -> int • The argument n is assumed to be >=1 • f n return an • Let rec f n = • if n > 1 then k * (f (n-1) ) + 1 • else 1;;
Recursive function with unchanging argument • Q: what would be the output? • let k = 3;; • let rec f n = • if n > 1 then k * (f (n-1) ) + 1 • else 1;; • f 3;; • In f, k is fixed • When f is defined, k=3. Thus, an = 3an + 1 • If we want an=5an+1, then function f cannot be used. • How to let k be variable?
Recursive function with unchanging argument • Define f_gen that has a variable k • let f_gen k n = • if n > 1 then k * (f_gen k (n-1) ) + 1 • else 1;; • You can call f_gen with a variable k, thus k is set at the time f is called rather than f is defined. • But, note that the value k is not changing when f_gen is called inside f_gen. Only the argument n is changing. • This is ok because k is not used in the terminal condition.
Recursive function with unchanging argument • Define f_full that has the following sequence • an = k an-1 + p • a1 = q • let f_gen k p q n = • if n > 1 then k * (f_gen k p q (n-1) ) + p • else q;;
Recursive function having multiple outputs • Example sequence • an = 2an-1 + bn-1 • bn = an-1 + 2bn-1 • a1 = p • b1 = q • Define f_pair for the above sequence using tuple • Why use tuple?
Recursive function having multiple outputs • Example sequence • an = 2an-1 + bn-1 • bn = an-1 + 2bn-1 • a1 = p • b1 = q • Type of f_pair: int -> int * int (or, int -> (int * int)) • f_pair n returns (an, bn)
Recursive function having multiple outputs • Example sequence • an = 2an-1 + bn-1 • bn = an-1 + 2bn-1 • a1 = p • b1 = q • let rec f_pair n = • Ifn > 1 then • Let (a, b) = f_pair (n-1) in (2*a + b, a + 2*b) • Else • (p, q);;
Recursive function having multiple variable arguments • How to compute the GCD (Greatest Common Divisor) (최대공약수) of two values a and b? • E.g., a=12 and 6=18, gcd is 6 • Euclidean Algorithm: Keep subtracting smaller value from larger value until two values become equal • Let rec gcd a b = • If a > b then gcd (a-b) b • Else if a < b then gcd a (b-a) • Else a;;