270 likes | 399 Views
COS220 Concepts of PLs AUBG, COS dept. Exercise 08a Iteration and Recursion in Procedure Oriented Programming Reference: lecture 08. Exercise Topics:. Build and test a set of functions that illustrate the implementation of certain iterative and recursive algorithms. Function description.
E N D
COS220 Concepts of PLs AUBG, COS dept Exercise 08a Iteration and Recursion in Procedure Oriented Programming Reference: lecture 08 assoc. prof. Stoyan Bonev
Exercise Topics: • Build and test a set of functions that illustrate the implementation of certain iterative and recursive algorithms. assoc. prof. Stoyan Bonev
Function description Function prototype (signature) Iteration Recursion Factorial int facti(int n); int factr(int n); Greatest common divisor int gcdi(int m, int n); int gcdr(int m, int n); Sum of natural numbers 0,1,2,3, … int sumi(int n); int sumr(int n); Sum of elements of 1dimensioned array int sumi(int ar[], int n); int sumr(int ar[], int n); To calculate element of Fibonacci series int fibi(int n); int fibr(int n); To calculate square root; yn+1=1/2(x/yn+yn) y0=1 sqrtr(x,yn,eps) = yn, |yn2-x|<eps, else = sqrtr(x, (yn2+x)/2yn, eps) Ackermann function int Ar(int m, int n); Hanoi towers game Task 1 Build and test a set of iterative and recursive functions to calculate: assoc. prof. Stoyan Bonev
Task 2 Describe the algorithm that the following function performs: void printd(int n) { if (n<0) { putchar(‘-‘); n=-n; } if (n/10) printd(n/10); putchar(n%10 + ‘0’); } assoc. prof. Stoyan Bonev
Task 4 Build and test a recursive function to return the product on two integer values. Hint: Use definition of multiplication as a function in terms of a conditional expression: m * n ≡ mulr(m,n) = [ (n==0)->0, (n==1)->m, m + mulr(m, n-1) ] Try to formulate and solve similar tasks for addition, subtraction and division operators. assoc. prof. Stoyan Bonev
Task 5. Build a program with iterative and recursive functions to illustrate the linear search algorithm and the binary search algorithm (RecursiveLinBinSearch.cpp): See the next page assoc. prof. Stoyan Bonev
Linear search algorithm 1. Assume the target has not been found. 2. Start with the initial array element. 3. Repeat while the target is not found and there are more array elements { 4. If the current element matches the target 5. Set flag to indicate the target was found Else 6. Advance to the next array element } // end of repeat 7. If the target was found 8. Return the target index as a search result Else 9. Return –1 as a search result. Binary search algorithm 1. Assume array sorted and target not found 2. Let low be subscript of initial array element. 3. Let high be subscript of the last array element. 4. Repeat as long as high>low (low<=high) and the target has not been found { 5. Let mid be subscript of the element halfway between low and high 6. If element at mid is the target 7. Return mid (the target index) as search result Else 8. If the element at mid is > the target 9. Let high be mid – 1 Else 10. Let low be mid + 1 } // end of repeat 11. return –1 as a search result. assoc. prof. Stoyan Bonev
Iterative Linear Search int LinSearchIterative(int target, int tab[], int size) { int k = 0; while ( k < size ) { if (target == tab[k]) return k; k++; } return -1; } Recursive Linear search int LinSearchRecursive(int target,int tab[], int low, int high) { if (high < low) return -1; if (target == tab[high]) return high; return LinSearchRecursive(target, tab, low, high-1); } assoc. prof. Stoyan Bonev
Iterative Binary search int BinSearchIterative(int target, int table[], int size) { int low, high, mid; low = 0; high = size - 1; while ( low <= high ) { mid = (low + high) / 2; if (target == table[mid]) return mid; if (target < table[mid]) high = mid - 1; if (target > table[mid]) low = mid + 1; } return -1; } Recursive Binary search int BinSearchRecursive(int target, int table[], int low, int high) { if (low > high) return -1; int mid; mid = (low + high) / 2; if (target == table[mid]) return mid; if (target < table[mid]) // low half of the table, high = mid-1; { return BinSearchRecursive(target, table, low, mid-1); } if (target > table[mid]) // high half of the table, low = mid+1; { return BinSearchRecursive(target, table, mid+1, high); } } assoc. prof. Stoyan Bonev
More info on Recursion Recursive Helper Methods assoc. prof. Stoyan Bonev
More info on Recursion Sometimes you can find a recursive solution by slightly changing the original problem. The new method is called recursive helper method. Example: the palindrom problem: isPali(), isPalr(), isPalrHelper() assoc. prof. Stoyan Bonev
The iterative isPali() bool isPali(string p) { int i=0, j = p.length()-1; //for(int i=0, int j=p.length()-1; i<j; i++, j--) while(i<j) { if(p.at(i) != p.at(j) ) return false; i++; j--; } return true; } // end of isPali assoc. prof. Stoyan Bonev
The recursive isPalr() bool isPalr(string p) { if (p.length() <= 1) return true; if(p.at(0) != p.at(p.length()-1) ) return false; return isPalr(p.substr(1,p.length()-2)); } // end of isPalr assoc. prof. Stoyan Bonev
Comments on isPalr() The recursive isPalr() is not efficient because it creates a new substring for every recursive call. To avoid creating new strings, you can use the low and high indices to indicate the range of the substring. These two indices must be passed to recursive method. Original method isPalr(string s) has to be overloaded to isPalr(string s, int low, int high) assoc. prof. Stoyan Bonev
The recursive helper method bool isPalrHelper(string p) { return isPalrHelper(p, 0, p.length()-1 ); } bool isPalrHelper(string p, int low, int high ) { if (low >= high) return true; // Base case if (p.at(low) != p.at(high) ) return false; return isPalrHelper(p, low+1, high-1); } // end of isPalrHelper assoc. prof. Stoyan Bonev
The main() function void main() { string pom; cout << "Type a string to test as palindrome:"; cin >> pom; while ( !cin.eof()) { cout << "\nThe string that You just typed: " << pom; if (isPali(pom) && isPalr(pom) && isPalrHelper(pom)) cout << " is palindrome"; else cout << " is not palindrome"; cout << "\nType another string to test as palindrome:"; cin >> pom; } } // end of Main assoc. prof. Stoyan Bonev
More info on Recursion Tail Recursion assoc. prof. Stoyan Bonev
More info on Recursion A tail recursive method is efficient for reducing stack size. A recursive method is said to be tail recursive if there are no pending operations to be performed on return from a recursive call. recMethodA() { recMethodB() { … … … recMethodB(); recMethodA(); … } } assoc. prof. Stoyan Bonev
More info on Recursion Examplec: GCDr() is tail-recursive method Factr() is nontail-recursive method assoc. prof. Stoyan Bonev
More info on Recursion Tail recursion is desirable because the method ends when the last recursive call ends. There is no need to store intermediate calls in the stack. assoc. prof. Stoyan Bonev
More info on Recursion A nontail-recursive method can often be converted to tail-recursive method by using auxiliary parameters. These parameters are used to contain result. assoc. prof. Stoyan Bonev
nontail-recursive method factr int factr(int n) { if (n==0) return 1; return n*factr(n-1); } assoc. prof. Stoyan Bonev
tail-recursive method factr int factrTailRec(int n) { return factrTailRec(n, 1); } int factrTailRec(int n, int result) { if (n==0) return result; else return factrTailRec(n-1, n*result); } assoc. prof. Stoyan Bonev
The main() method void main() { // DEMO on Tail Recursion with // helper methods in recursion cout << "Factorial classic recursion & tail recursion"; for (int i=0; i<=10; i++) { cout<<endl<<i<<" "<<factr(i)<<" "<<factrTailRec(i); } } assoc. prof. Stoyan Bonev
More info on Recursion Indirect Recursion Nested Recursion Excessive Recursion assoc. prof. Stoyan Bonev
. Quiz #2 On Functions, Iteration and Recursion planned for end of the class assoc. prof. Stoyan Bonev
Thank You For Your Attention assoc. prof. Stoyan Bonev