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