Recursive functions
Outline In this presentation, we will: Define literal data Describe: Integers Characters Strings Floating-point numbers (reals) Boolean
Recursion In the previous topic, we saw how a function could call itself If p < x ≤ 2p, you can calculates sin(x) by calculating –sin(x – p) If p/2 < x ≤ p, you can calculates sin(x) by calculating sin(p /2 – x) When a function calls itself That call is said to be a recursive call The process is described as recursion Etymology: From the Latin verb recurrere meaning “to run back” or “to run again” From English verb recur meaning “to occur again periodically or repeatedly”
Factorial There are two approaches to defining the factorial: n! is the product of the integers from 1 to n n! = n (n – 1)! and 0! = 1 We will write this as The first definition is explicit: it tells you how to calculate it The second definition defines n! in terms of (n – 1)! To calculate n!, you must calculate (n – 1)! To calculate (n – 1)!, you must calculate (n – 2)! At some point, you need a result, and in this case, it is 0! = 1
n! is the product of the integers from 1 to n Factorial The first definition, n! is the product of the integers from 1 to n is explicit: it tells you how to calculate it For example,
Factorial The second definition, is implicit: it tells you how to calculate it in terms of other factorials For example,
Fibonacci numbers Implementing this unsigned long factorial( unsigned long n ) { if ( n == 0 ) { return 1; } else { return n*factorial( n - 1 ); }
Binomial coefficients There are two approaches to the defining the binomial coefficients:
Binomial coefficients The first is explicit: Assuming we know factorials, we can calculate this easily:
Binomial coefficients The second is recursive:
Binomial coefficients For example: – – Thus, – Thus, –
Binomial coefficients Implementing this unsigned long binomial( unsigned long n, unsigned long k ) { if ( k > n ) { return 0; } else if ( (k == 0) || (k == n) ) { return 1; } else { return binomial( n – 1, k ) + binomial( n - 1, k - 1 ); }
Fibonacci numbers In some cases, we may not have an explicit formula, and instead we only have a recursive definition: We could start by calculating 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … and the next number is always the sum of the previous two
Fibonacci numbers Implementing this unsigned long fibonacci( unsigned long n ) { if ( n == 0 ) { return 0; } else if ( n == 1 ) { return 1; } else { return fibonacci( n - 1 ) + fibonacci( n - 2 ); }
Factorial To start, let’s redefine the factorial as a function:
Factorial Note that the conditions can be implemented using conditional statements: unsigned long factorial( unsigned long n ) { if ( n == 0 ) { return 1; } else { return n * factorial( n - 1 ); }
Binomial coefficients Let us redefine the binomial coefficients as a function:
Binomial coefficients Note that the conditions can be implemented using conditional statements: unsigned long binomial( unsigned long n, unsigned long k ) { if ( (k == 0) || (k == n) ) { return 1; } else if ( n >= 1 ) { return binomial( n - 1, k ) + binomial( n – 1, k - 1 ); }
Fibonacci numbers Some functions are more easily stated recursively: There is a closed form solution:
Fibonacci numbers How would you implement this function?
Towers of Hanoi Instead of describing such representations in words, there is a more concise format in computer science: regular expressions: [+-]?[1-9][0-9]* Other representations are possible We will see those in future lessons
Greatest common divisor The greatest common divisor can be defined as This assumes m ≥ n ≥ 0 Implemented, this is: unsigned long gcd( unsigned long m, unsigned long n ) { if ( m < n ) { return gcd ( n, m ); } else if ( m == 0 ) { return n; } else { return gcd( n, m % n ); }
Finding a path through a maze How do we find a path through a maze?
Finding a path through a maze Mark all squares as unvisited, and place us at the starting square Our algorithm is If we reached the destination square, we are finished Otherwise, Mark this square as visited If we can go north and that square is not visited: Repeat this algorithm starting at that square If we can go west and that square is not visited: If we can go south and that square is not visited: If we can go east and that square is not visited: If we reach this point, no path exists
Tail recursion What if the result of a recursive function call is the result of the current function call, such as unsigned long gcd( unsigned long m, unsigned long n ) { if ( m < n ) { return gcd( n, m ); } else if ( n == 0 ) { return m; } else { return gcd( n, m % n ); }
Tail recursion In this case, the memory allocated for any previous function calls is no longer necessary—it is possible to re-use the space on the stack for the current unsigned long gcd( unsigned long m, unsigned long n ) { if ( m < n ) { return gcd( n, m ); } else if ( n == 0 ) { return m; } else { return gcd( n, m % n ); }
Going forward… Do we discuss head and tail recursion? Other examples?
Summary After this lesson, you now Understand the idea of literal data in source code You understand how to encode Integers Characters Strings Floating-point numbers (reals) Boolean in your source code Everything else in C++ deals with the storage and manipulation of data
References [1] Wikipedia https://en.wikipedia.org/wiki/Literal_(computer_programming) [2] cplusplus.com tutorial http://www.cplusplus.com/doc/tutorial/constants/ [3] C++ reference https://en.cppreference.com/w/cpp/language/integer_literal https://en.cppreference.com/w/c/language/integer_constant
Acknowledgments Proof read by Dr. Thomas McConkey
Colophon These slides were prepared using the Georgia typeface. Mathematical equations use Times New Roman, and source code is presented using Consolas. The photographs of lilacs in bloom appearing on the title slide and accenting the top of each other slide were taken at the Royal Botanical Gardens on May 27, 2018 by Douglas Wilhelm Harder. Please see https://www.rbg.ca/ for more information.
Disclaimer These slides are provided for the ece 150 Fundamentals of Programming course taught at the University of Waterloo. The material in it reflects the authors’ best judgment in light of the information available to them at the time of preparation. Any reliance on these course slides by any party for any other purpose are the responsibility of such parties. The authors accept no responsibility for damages, if any, suffered by any party as a result of decisions made or actions based on these course slides for any other purpose than that for which it was intended.