Here below a little program in Java that implements 2 classes (in fact, they are 3 + an extra utility Stopwatch class from my previous post http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html). There is the main class, called Fiborial (Fibo(nnacci)+(Facto)rial) that implements the Fibonacci and the Factorial algorithms in two ways, one Recursive (using recursion) and the other Imperative (using loops and states). The second class is just an instance class that does the same thing, but its there just to show the difference between static and instance classes, and finally the third one (which will not appear in other languages) is the Program class which has the static execution method "main".
You can also find 3 more little examples at the bottom. One prints out the Factorial's Series and Fibonacci's Series, the second one just shows a class that mixes both: static and instance members, and finally the third one that uses different return types (including java.math.BigInteger) for the Factorial method to compare the timing and result.
As with the previous posts, you can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you some more basics of the Programming Language.
There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2011/01/new-series-factorial-and-fibonacci.html
The Fiborial Program
// Factorial and Fibonacci in Java package fiborial; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; // Instance Class // static is not a class modifier in Java public class StaticFiborial { // Static Field private static String className; // Static Constructor/Initializer static { className = "Static Constructor"; System.out.println(className); } // Static Method - Factorial Recursive public static BigInteger factorialR(int n) { if (n == 1) return BigInteger.ONE; else return BigInteger.valueOf(n).multiply(factorialR(n - 1)); } // Static Method - Factorial Imperative public static BigInteger factorialI(int n) { BigInteger res = BigInteger.ONE; for (int i = n; i >= 1; i--) { res = res.multiply(BigInteger.valueOf(i)); } return res; } // Static Method - Fibonacci Recursive public static long fibonacciR(int n) { if (n < 2) return 1; else return fibonacciR(n - 1) + fibonacciR(n - 2); } // Static Method - Fibonacci Imperative public static long fibonacciI(int n) { long pre, cur, tmp = 0; pre = cur = 1; for (int i = 2; i <= n; i++) { tmp = cur + pre; pre = cur; cur = tmp; } return cur; } // Static Method - Benchmarking Algorithms public static void benchmarkAlgorithm(int algorithm, List<Integer> values) { Stopwatch timer = new Stopwatch(); int i, testValue; BigInteger facTimeResult = BigInteger.valueOf(0); long fibTimeResult = 0; i = testValue = 0; // "Switch" Flow Control Statement switch (algorithm) { case 1: System.out.println("\nFactorial Imperative:"); // "For" Loop Statement for (i = 0; i < values.size(); i++) { testValue = ((Integer)values.get(i)).intValue(); // Taking Time timer.start(); facTimeResult = factorialI(testValue); timer.stop(); // Getting Time System.out.println(" (" + testValue + ") = " + timer.getElapsed()); } break; case 2: System.out.println("\nFactorial Recursive:"); // "While" Loop Statement while (i < values.size()) { testValue = ((Integer)values.get(i)).intValue(); // Taking Time timer.start(); facTimeResult = factorialR(testValue); timer.stop(); // Getting Time System.out.println(" (" + testValue + ") = " + timer.getElapsed()); i++; } break; case 3: System.out.println("\nFibonacci Imperative:"); // "Do-While" Loop Statement do { testValue = ((Integer)values.get(i)).intValue(); // Taking Time timer.start(); fibTimeResult = fibonacciI(testValue); timer.stop(); // Getting Time System.out.println(" (" + testValue + ") = " + timer.getElapsed()); i++; } while (i < values.size()); break; case 4: System.out.println("\nFibonacci Recursive:"); // "For Each" Loop Statement for (Integer item : values) { testValue = item; // Taking Time timer.start(); fibTimeResult = fibonacciR(testValue); timer.stop(); // Getting Time System.out.println(" (" + testValue + ") = " + timer.getElapsed()); } break; default: System.out.println("DONG!"); break; } } }
package fiborial; import java.math.BigInteger; // Instance Class public class InstanceFiborial { // Instance Field private String className; // Instance Constructor public InstanceFiborial() { this.className = "Instance Constructor"; System.out.println(this.className); } // Instance Method - Factorial Recursive public BigInteger factorialR(int n) { // Calling Static Method return StaticFiborial.factorialR(n); } // Instance Method - Factorial Imperative public BigInteger factorialI(int n) { // Calling Static Method return StaticFiborial.factorialI(n); } // Instance Method - Fibonacci Recursive public long fibonacciR(int n) { // Calling Static Method return StaticFiborial.fibonacciR(n); } // Instance Method - Factorial Imperative public long fibonacciI(int n) { // Calling Static Method return StaticFiborial.fibonacciI(n); } }
package fiborial; import java.util.Scanner; import java.util.ArrayList; import java.util.List; public class StaticFiborialProgram { public static void main(String[] args) { System.out.println("\nStatic Class"); // Calling Static Class and Methods // No instantiation needed. Calling method directly from the class System.out.println("FacImp(5) = " + StaticFiborial.factorialI(5)); System.out.println("FacRec(5) = " + StaticFiborial.factorialR(5)); System.out.println("FibImp(11)= " + StaticFiborial.fibonacciI(11)); System.out.println("FibRec(11)= " + StaticFiborial.fibonacciR(11)); System.out.println("\nInstance Class"); // Calling Instance Class and Methods // Need to instantiate before using. Calling method from instantiated object InstanceFiborial ff = new InstanceFiborial(); System.out.println("FacImp(5) = " + ff.factorialI(5)); System.out.println("FacRec(5) = " + ff.factorialR(5)); System.out.println("FibImp(11)= " + ff.fibonacciI(11)); System.out.println("FibRec(11)= " + ff.fibonacciR(11)); // Create a (generic) list of integer values to test // From 5 to 50 by 5 List<Integer> values = new ArrayList<Integer>(); for(int i = 5; i <= 50; i += 5) values.add(i); // Benchmarking Fibonacci // 1 = Factorial Imperative StaticFiborial.benchmarkAlgorithm(1, values); // 2 = Factorial Recursive StaticFiborial.benchmarkAlgorithm(2, values); // Benchmarking Factorial // 3 = Fibonacci Imperative StaticFiborial.benchmarkAlgorithm(3, values); // 4 = Fibonacci Recursive StaticFiborial.benchmarkAlgorithm(4, values); // Stop and exit System.out.println("Press any key to exit..."); Scanner in = new Scanner(System.in); String line = in.nextLine(); in.close(); } }
And the Output is:
Printing the Factorial and Fibonacci Series
package fiborialseries; import java.math.BigInteger; import java.lang.StringBuffer; class Fiborial { // Using a StringBuffer as a list of string elements public static String getFactorialSeries(int n) { // Create the String that will hold the list StringBuffer series = new StringBuffer(); // We begin by concatenating the number you want to calculate // in the following format: "!# =" series.append("!"); series.append(n); series.append(" = "); // We iterate backwards through the elements of the series for (int i = n; i <= n && i > 0; i--) { // and append it to the list series.append(i); if (i > 1) series.append(" * "); else series.append(" = "); } // Get the result from the Factorial Method // and append it to the end of the list series.append(factorial(n)); // return the list as a string return series.toString(); } // Using a StringBuffer as a list of string elements public static String getFibonnaciSeries(int n) { // Create the String that will hold the list StringBuffer series = new StringBuffer(); // We begin by concatenating the first 3 values which // are always constant series.append("0, 1, 1"); // Then we calculate the Fibonacci of each element // and add append it to the list for (int i = 2; i <= n; i++) { if (i < n) series.append(", "); else series.append(" = "); series.append(fibonacci(i)); } // return the list as a string return series.toString(); } public static BigInteger factorial(int n) { if (n == 1) return BigInteger.ONE; else return BigInteger.valueOf(n).multiply(factorial(n - 1)); } public static long fibonacci(int n) { if (n < 2) return 1; else return fibonacci(n - 1) + fibonacci(n - 2); } }
package fiborialseries; class FiborialExtrasProgram { public static void main(String[] args) { // Printing Factorial Series System.out.println(""); System.out.println(Fiborial.getFactorialSeries(5)); System.out.println(Fiborial.getFactorialSeries(7)); System.out.println(Fiborial.getFactorialSeries(9)); System.out.println(Fiborial.getFactorialSeries(11)); System.out.println(Fiborial.getFactorialSeries(40)); // Printing Fibonacci Series System.out.println(""); System.out.println(Fiborial.getFibonnaciSeries(5)); System.out.println(Fiborial.getFibonnaciSeries(7)); System.out.println(Fiborial.getFibonnaciSeries(9)); System.out.println(Fiborial.getFibonnaciSeries(11)); System.out.println(Fiborial.getFibonnaciSeries(40)); } }
And the Output is:
Mixing Instance and Static Members in the same Class
Instance classes can contain both, instance and static members such as: fields, getters/setters, constructors/initializers, methods, etc.
package fiborialextrasjava2; // Instance Class class Fiborial { // Instance Field private int instanceCount; // Static Field private static int staticCount; // Instance Read-Only Getter // Within instance members, you can always use // the "this" reference pointer to access your (instance) members. public int getInstanceCount() { return this.instanceCount; } // Static Read-Only Getter // As with Static Methods, you cannot reference your class members // with the "this" reference pointer since static members are not // instantiated. public static int getStaticCount() { return staticCount; } // Instance Constructor public Fiborial() { this.instanceCount = 0; System.out.println("\nInstance Constructor " + this.instanceCount); } // Static Constructor static { staticCount = 0; System.out.println("\nStatic Constructor " + staticCount); } // Instance Method public void factorial(int n) { this.instanceCount += 1; System.out.println("\nFactorial(" + n + ")"); } // Static Method public static void fibonacci(int n) { staticCount += 1; System.out.println("\nFibonacci(" + n + ")"); } }
package fiborialextrasjava2; class FiborialExtras2Program { public static void main(String[] args) { // Calling Static Constructor and Methods // No need to instantiate Fiborial.fibonacci(5); // Calling Instance Constructor and Methods // Instance required Fiborial fib = new Fiborial(); fib.factorial(5); Fiborial.fibonacci(15); fib.factorial(5); // Calling Instance Constructor and Methods // for a second object Fiborial fib2 = new Fiborial(); fib2.factorial(5); System.out.println(""); // Calling Static Property System.out.println("Static Count = " + Fiborial.getStaticCount()); // Calling Instance Property of object 1 and 2 System.out.println("Instance 1 Count = " + fib.getInstanceCount()); System.out.println("Instance 2 Count = " + fib2.getInstanceCount()); } }
And the Output is:
Factorial using java.lang.Long, java.lang.Double, java.math.BigInteger
package fiborialextrasjava3; import java.math.BigInteger; class FiborialExtrasProgram { public static void main(String[] args) { Stopwatch timer = new Stopwatch(); long facIntResult = 0; double facDblResult = 0; BigInteger facBigResult = BigInteger.valueOf(0); System.out.println("\nFactorial using Int64"); // Benchmark Factorial using Int64 for (int i = 5; i <= 50; i += 5) { timer.start(); facIntResult = factorialInt64(i); timer.stop(); System.out.println(" (" + i + ") = " + timer.getElapsed() + " : " + facIntResult); } System.out.println("\nFactorial using Double"); // Benchmark Factorial using Double for (int i = 5; i <= 50; i += 5) { timer.start(); facDblResult = factorialDouble(i); timer.stop(); System.out.println(" (" + i + ") = " + timer.getElapsed() + " : " + facDblResult); } System.out.println("\nFactorial using BigInteger"); // Benchmark Factorial using BigInteger for (int i = 5; i <= 50; i += 5) { timer.start(); facBigResult = factorialBigInteger(i); timer.stop(); System.out.println(" (" + i + ") = " + timer.getElapsed() + " : " + facBigResult); } } // Long Factorial public static long factorialInt64(int n) { if (n == 1) return 1; else return n * factorialInt64(n - 1); } // Double Factorial public static double factorialDouble(int n) { if (n == 1) return 1; else return n * factorialDouble(n - 1); } // BigInteger Factorial public static BigInteger factorialBigInteger(int n) { if (n == 1) return BigInteger.ONE; else return BigInteger.valueOf(n).multiply(factorialBigInteger(n - 1)); } }
And the Output is:
No comments:
Post a Comment