Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CPAN322 Java Application Programming Lecture #3: Recursion Recursion is a technique for breaking up complex computational problems into simpler ones. Most recursive techniques can be solved with loops, but using recursion make complex problems solving easier. However, complex recursive requires more CPU and memory time than iteration. There must be special case(s) to terminate the recursion. Otherwise you may have an infinite recursion. Also each recursive call must simplify the computation process. An iterative method is a method that uses loops to repeat an action. A recursive method is a method that call itself. Each time a method is called , Java allocates new space in its internal stack for all the variables in the method. When the method is called recursively, a new set of variables will be allocated on the stack automatically. A mutual recursion occurs when a set of methods calls each other recursively. This is considered an indirect approach of recursion. A method cam call some other method(s), which in turn call the original method back. If the solution of a problem is composite of repeated computations, then recursion would be the best technique to use. For example, let consider the factorial for an integer number. The factorial for an integer number n is defied as follows: n!=n*(n-1)*(n-2)*…*2*1 1!=1 0!=1. Even though we can find the factorial using a loop as shown in the following method: public int factorial1(int n) { int total=n; while( n>1) { total=total* (n-1); n=n-1; } return total; } 1 We can also solve this problem using recursion. If we look at the definition of the factorial, we notice that we can rewrite it as follow: n=n*(n-1)! This means that in order to calculate the factorial of n, we need first to calculate the factorial of (n-1) and to calculate the factorial of (n-1) we need to find the factorial of (n-2) and so on. Therefore we can rewrite the above function using recursion as follows: public static int factorial(int n) { if (n==1) return 1; else return n*factorial (n-1); } Recursion can be more efficient with more complex problems. Even though sometimes a recursion solution may run slower that an iteration solution. The recursive solution is easier to understand and implement. Examples: Ex1:countChar.java In this example we will develop a recursive method to calculate the number of occurrence of a character in a string. import javax.swing.JOptionPane; public class countChar { public countChar(String word, char arg) { System.out.println(countChar(word,arg)); } public static void main(String[] args) { String word= JOptionPane.showInputDialog("Enter a string to be searched "); char ch = JOptionPane.showInputDialog("Enter a character to search for ").charAt(0); new countChar(word,ch); 2 } public int countChar(String s, char ch) { if (s.length() == 0) return 0; else if (s.charAt(0) == ch) return 1 + countChar(s.substring(1), ch); else return 0 + countChar(s.substring(1), ch); } } Ex2: factorial.java The class in the following example uses recursive method to calculate the factorial of an integer number. import javax.swing.JOptionPane; public class recursion { public recursion(int n) { System.out.println("The factorial of "+n+ " is "+recursionFactorial(n)); } public static void main (String args[]) { String input = JOptionPane.showInputDialog("Enter an integer: "); int n = Integer.parseInt(input); new recursion(n); } public int recursionFactorial(int n) { if (n==1 || n==0) return 1; else return n*recursionFactorial (n-1); } } 3 Ex3:Fibonacci.java In this example we will find the Fibonacci sequence of an integer. It is defined as follows: F1 1 F2 1 and Fn Fn1 Fn2 Therefore F3=2, F4=3, F4=5, and so on. import javax.swing.JOptionPane; public class Fibonacci { public Fibonacci(int n) { System.out.println("fibonacci sequence for " + n + " is " + fib(n)); } public static void main(String[] args) { String input = JOptionPane.showInputDialog("Enter an integer: "); int n = Integer.parseInt(input); new Fibonacci(n); } public int fib(int n) { if (n <= 2) return 1; else return fib(n - 1) + fib(n - 2); } } 4 Ex4 drawing.java Recursion can be used to draw a sequence of repeated shapes. The following Application draws a sequence of rectangles. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class drawing extends JFrame { public drawing () { super("Drawing example"); setSize(300,300); setVisible(true); } public void paint(Graphics g) { super.paint(g); g.setColor(Color.blue); draw(g,100,100); } public void draw(Graphics g,int width,int height) { g.drawRect(50,50,width,height); if (width >0 && height >0) { width=width-10; height=height-10; draw(g,width,height); } } public static void main(String args[]) { drawing dr=new drawing (); dr.addWindowListener(new WindowAdapter (){ public void windowClosing(WindowEvent e){System.exit(0);}}); } } 5 Ex5: Tower of Hanoi puzzle This puzzle consists of 3 pegs. A stack of disks of decreased size ( larger disks are on the bottom) must be transported from the left most peg to the right most one. The middle peg can be used as a temporary storage. One disk can be moved at anytime and larger disks cannot be placed on top of smaller disks. import javax.swing.JOptionPane; public class puzzleEx { private int disksTotal; public puzzleEx (int disks) { disksTotal= disks; moveTower (disksTotal, 1, 3, 2); } private void moveTower (int numDisks, int start, int end, int temp) { if (numDisks == 1) moveOneDisk (start, end); else { moveTower (numDisks-1, start, temp, end); moveOneDisk (start, end); moveTower (numDisks-1, temp, end, start); } } private void moveOneDisk (int start, int end) { System.out.println ("Move one disk from " + start + " to " + end); } public static void main (String[] args) { String input= JOptionPane.showInputDialog("Enter the number of disks "); new puzzleEx(Integer.parseInt(input)); } } 6 Ex6:permutationEx.java The permutation of a string is the possible rearrangements of the letters in the strings without any repetitions . There is n! Ways to permute a string of size n. For example, there are 2 ways to permute the string ab: ab and ba. Three are 6 ways to permute the string abc: abc, acb, bac,bcd,cab, and cba. If we do not want to use the fact that there are n! ways to permute a string. The following example will find how many ways we can rearrange the letters in a string by using recursive method: import javax.swing.JOptionPane; public class permutationEx { private String word; private int i; private static String tempW; public permutationEx(String w) { word=w; System.out.println("There are "+p(word)+" ways to rearrange the letters "+word); } public static int p(String w) { int i=w.length(); if (i==1) { i--; return 1; } else { int r=0; while (i>0) { r+=p(w.substring(0,i-1)+w.substring(i)); i--; } return r; }} public static void main(String[] args) { String input= JOptionPane.showInputDialog("Enter a string "); 7 permutationEx pe=new permutationEx(input); } } Ex7: PermutationGeneratorTest.java The following example will generate all the possible permutations of a string: import javax.swing.JOptionPane; public class PermutationGeneratorTest { private String word; private int current; private PermutationGeneratorTest tailGenerator; public PermutationGeneratorTest(String aWord) { word = aWord; current = 0; if (word.length() > 1) tailGenerator = new PermutationGeneratorTest(word.substring(1)); } public String nextPermutation() { if (word.length() == 1) { current++; return word; } String r = word.charAt(current) + tailGenerator.nextPermutation(); if (!tailGenerator.hasMorePermutations()) { current++; if (current < word.length()) { String tailString = word.substring(0, current) + word.substring(current + 1); tailGenerator = new PermutationGeneratorTest(tailString); } } return r; } public static void main(String[] args) { 8 String input= JOptionPane.showInputDialog("Enter a string "); System.out.println("The following is the possible permutation of "+input); PermutationGeneratorTest generator = new PermutationGeneratorTest(input); while (generator.hasMorePermutations()) System.out.println(generator.nextPermutation()); } public boolean hasMorePermutations() { return current < word.length(); } } To simplify the code, lets look at some example cases: The simplest case is a one letter string . The permutation is simply that string. To find the permutation of a string with n letters, we need to do the following: Keep track of the current position in the string using the variable current. Starting from the first letter in the string, we take one letter , and calculate the permutation for the rest of the characters. Increase the current position and repeat the same process until the end of the string. To find the permutation of abc for example, we take the letter a first and calculate the permutation for bc. After that we take the letter b and calculate the permutation for ac. At the end we take the letter c and calculate the permutation for ab. The permutations of the strings :ab,ac,bc are calculated in the same way. 9