Printing V shape using recursion only - java

I'm trying to print out a shape of the letter V using recursion only. I have seen some of the codes in this website related to my problem, but the majority use loops instead of recursion.
Here's my code:
public class Pattern {
public static void main(String[] args) {
printPattern(5);
}
public static void Pattern(int count, String s) {
if (count == 0) {
return;
}
System.out.print(s);
Pattern(count - 1, s);
}
public static void upperhalf(int count, int max) {
if (count == 0) {
return;
}
Pattern(max - count, " ");
Pattern(count, "* ");
System.out.println();
upperhalf(count - 1, max);
}
public static void printPattern(int n) {
upperhalf(n, n);
}
}
Output:
* * * * *
* * * *
* * *
* *
*
The output I want:
* *
* *
* *
* *
*

One way of solving it. Replace your two consecutive Pattern calls with this:
Pattern(max - count, " ");
Pattern(1, "* ");
Pattern(count - 2, " ");
Pattern(1, count > 1 ? "* " : "");
(Ie your first Pattern call, then an explicit for a single *, then a few spaces (2 less than in your approach), then the last *).
You also need to change the exit statement slightly:
public static void Pattern(int count, String s) {
if (count <= 0) { // <= instead of ==
return;
}

If your interested, here is one way to do it by by taking successive substrings.
Here are some key points.
The starting size is modified to ensure it is odd. This guarantees the V will be uniform.
The passed string consists of white space followed by an asterisk. The left asterisk is supplied by the recursive method.
The indentation is used to properly position the start of the remaining string.
int size = 10;
String v = " ".repeat((size | 1) - 2) + "*";
V(v,0);
public static void V(String v, int indent) {
System.out.println(" ".repeat(indent)+ "*" + v);
if (v.isEmpty()) {
return;
}
V(v.substring(2),indent+1);
}

Related

Genric in Java Error --> class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Comparable;

Question
Create a class named KeepSmallArray that uses an array to implement the KeepSmallInterface. Use the program TestKeepSmall to test your implementation.
Basically i have to drop the two smallest scores from the assignement.
Key Points
KeepSmallArray object needs to be told at creation time how many grades (or whatever) it should keep track of.
Hints
helpful if you make the array one space larger than it "needs" to be. For example, if it's remembering 2 grades, make the array size 3.
You need to keep the elements of the array in order. Consider using the insert algorithm.
Error
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Comparable; ([Ljava.lang.Object; and [Ljava.lang.Comparable; are in module java.base of loader 'bootstrap')
Attempted Solution
Tried error handling and changed some stuff around but that didnt help
however the problem seems to be in the constructor of the keepSmallArray class.
My code
TestKeepSmall
public class TestKeepSmall {
public static final int NUM_ASGNS = 10;
public static final Scanner kbd = new Scanner(System.in);
public static final Random r = new Random();
public static void main(String[] args) {
for (int numDrops = 2; numDrops < NUM_ASGNS / 2; ++numDrops) {
int numKeeps = NUM_ASGNS - numDrops;
Integer[] grades = new Integer[numKeeps];
int numKept = 0;
System.out.println("\n"
+ "Keeping the best " + numKeeps + " of " + NUM_ASGNS
+ " assignments.");
KeepSmallInterface<Integer> drops = new KeepSmallArray<>(numDrops);
// KeepSmallInterface<Integer> drops = new KeepSmallHeap<>(numDrops);
// test size/capacity/isEmpty
System.out.println(" --> starts with size 0: "
+ (drops.size() == 0 ? "PASS" : "FAIL ***"));
System.out.println(" --> starts with given capacity: "
+ (drops.capacity() == numDrops ? "PASS" : "FAIL ***"));
System.out.println(" --> starts empty: "
+ (drops.isEmpty() ? "PASS" : "FAIL ***"));
// toArray
Object[] dropObjects = drops.toArray();
System.out.println(" --> toArray() returns correct size: "
+ (dropObjects.length == drops.size()
? "PASS" : "FAIL ***"));
Comparable[] dropComps = drops.toArray(new Comparable[3]);
System.out.println(" --> toArray(T[]) returns correct size: "
+ (dropComps.length == 3
? "PASS" : "FAIL ***"));
boolean nulledOut = true;
for (int i = 0; i < dropComps.length; ++i) {
if (dropComps[i] != null) {
nulledOut = false;
}
}
System.out.println(" --> toArray(T[]) nulls unused elements: "
+ (nulledOut ? "PASS" : "FAIL ***"));
pause();
// test add
for (int i = 1; i <= NUM_ASGNS; ++i) {
// get a grade from the user
int grade = randomGrade();
System.out.printf("A%02d grade is %3d.%n", i, grade);
// see if it belongs on the drop list
Integer keeper = drops.add(grade);
// if not, add it to the kept grades array
if (keeper != null) {
grades[numKept] = keeper;
++numKept;
// test get
Integer newMaxDrop = drops.get(drops.size() - 1);
System.out.println(" --> \"bumped out\" largest value: "
+ (newMaxDrop <= keeper ? "PASS" : "FAIL ***"
+ "(dropped " + keeper + " instead of "
+ newMaxDrop + ")"));
}
}
pause();
// toArray
dropObjects = drops.toArray();
System.out.println(" --> toArray() returns correct size: "
+ (dropObjects.length == drops.size()
? "PASS" : "FAIL ***"));
System.out.println("\n"
+ "Your dropped grades are " + Arrays.toString(dropObjects)
+ "\nYour kept grades are " + Arrays.toString(grades));
// toArray(T[])
dropComps = drops.toArray(new Comparable[3]);
System.out.println(" --> toArray(T[]) returns correct size: "
+ (dropComps.length == Math.max(3, drops.size())
? "PASS" : "FAIL ***"));
boolean inOrder = true;
int upperBound = Math.min(dropComps.length, drops.size());
for (int j = 1; j < upperBound; ++j) {
if (dropComps[j - 1].compareTo(dropComps[j]) > 0) {
inOrder = false;
}
}
System.out.println(" --> toArray(T[]) returns ordered array: "
+ (inOrder ? "PASS" : "FAIL ***"));
if (upperBound < dropComps.length) {
nulledOut = true;
for (int i = upperBound; i < dropComps.length; ++i) {
if (dropComps[i] != null) {
nulledOut = false;
}
}
System.out.println(" --> toArray(T[]) nulls unused elements: "
+ (nulledOut ? "PASS" : "FAIL ***"));
}
// contains
Integer in = oneOf(dropObjects);
System.out.println(" --> contains " + in + ": "
+ (drops.contains(in) ? "PASS" : "FAIL ***"));
Integer out = oneNotOf(dropObjects);
System.out.println(" --> !contains " + out + ": "
+ (!drops.contains(out) ? "PASS" : "FAIL ***"));
pause();
}
}
private static void pause() {
System.out.print("\n...press enter...");
kbd.nextLine();
System.out.println();
}
private static int randomGrade() {
return Math.max(r.nextInt(101), r.nextInt(90));
}
private static Integer oneOf(Object[] dropComps) {
int len = dropComps.length;
int n = r.nextInt(len);
return (Integer)dropComps[n];
}
private static Integer oneNotOf(Object[] dropComps) {
int len = dropComps.length;
int result = 0;
boolean ok;
do {
ok = true;
result = r.nextInt(101);
for (int i = 0; ok && i < dropComps.length; ++i) {
if (dropComps[i].equals(result)) {
ok = false;
}
}
} while (!ok);
return result;
}
}
KeepSmallArray
public class KeepSmallArray<T extends Comparable<? super T>>
implements KeepSmallInterface<T> {
private T[] smallArray;
public KeepSmallArray(int len) {
if(len <= 0) {
throw new NullPointerException();
}
smallArray = (T[]) new Object[len + 1];
}
#Override
public int size() {
int count = 0;
for (T item : smallArray) {
if (item != null) {
count++;
} else {
break;
}
}
return count;
}
#Override
public int capacity() {
return smallArray.length;
}
#Override
public boolean isEmpty() {
return size() == 0;
}
#Override
public void clear() {
try{
smallArray = (T[]) new Object[smallArray.length];
}
catch(Exception e){
}
}
#Override
public boolean contains(Object obj) {
for (T item : smallArray) {
if (obj.equals(item)) {
return true;
}
}
return false;
}
#Override
public Object[] toArray() {
return toArray(smallArray);
}
#Override
public Object[] toArray(Object[] array) {
if (array == null) {
throw new NullPointerException("given array is not initialized");
}
return array;
}
#Override
public T add(T newElement) {
if (newElement == null) {
throw new NullPointerException("null cannot be added");
}
return null;
}
#Override
public T get(int index) {
if (index < 0 || index > size() - 1) {
throw new IllegalArgumentException("index out of range");
}
return smallArray[index];
}
}
Keep Interface
/**
* A collection of "small" elements, sorted from smallest to largest.
* The collection contains a limited number of elements (its capacity).
* The client may request that a new element be added, but that element
* will only be added if there is room for it <em>or</em> if it is smaller
* than one of the elements currently stored in this container. In the
* latter case, the largest element in the container will be "bumped out"
* to make room for the new one.
* <p>
* Such a container may be used to keep track of assignment grades to be
* dropped from an average (for example, to track the two smallest of ten
* assignment grades). Alternatively, an appropriately programmed class
* could instead track the eight highest grades from ten (tho' such a class
* might better be called a "KeepBig" container).
*
*
*/
public interface KeepSmallInterface<T extends Comparable<? super T>> {
/**
* The number of elements currently in this container.
*
* #return the number of elements in this container.
*/
public int size();
/**
* The maximum number of elements this container can hold.
*
* #return the number of elements this container can hold.
*/
public int capacity();
/**
* Whether this bag is empty.
*
* #return true if this container has no elements in it; false otherwise.
*/
public boolean isEmpty();
/**
* Remove all the elements from this container.
*/
public void clear();
/**
* Consider the given element for addition to this container.
* If there is space available in this container, then given element
* will be added and <code>null</code> returned. Otherwise the
* largest of the current elements and the given element will be
* "bumped out" and returned. (Note that the given element may be
* the one "bumped out".)
*
* #param newElement the element to add.
* #return the element "bumped out" of this container;
* OR null if no element was "bumped out".
* #throws NullPointerException if <code>newElement</code> is
* <code>null</code>
*/
public T add(T newElement);
/**
* The smallest-but-<tt>i</tt> element in this container. For example,
* <code>get(0)</code> returns the smallest element in this container,
* while <code>get(2)</code> returns the third smallest element
* (<i>i.e.</i> the one with exactly two elements before it in the sorted
* order).
*
* #param index the number of smaller elements than the one requested.
* #return the smallest-but-<tt>index</tt> element in this container;
* OR null if there is none.
* #throws IllegalArgumentException if <tt>index</tt> is not in the range
* <code>0..size()-1</code>
*/
public T get(int index);
/**
* Whether the container contains the given element.
*
* #param obj the element to test for.
* #return true if it's present; false otherwise.
*/
public boolean contains(Object obj);
/**
* An array containing all the elements of this container, in order from
* smallest to largest.
*
* #return a sorted array with all this container's elements.
*/
public Object[] toArray();
/**
* Returns an array containing all of the elements in this container sorted
* from smallest to largest; the runtime type of the returned array is that
* of the given array. If the list fits in the given array, it is returned
* therein. Otherwise, a new array is allocated with the runtime type of
* the specified array and just large enuf to hold all this container's
* elements.
*
* #param <E> The base type of the passed-in array.
* #param array the array to place the elements in.
* #return a sorted array with all this container's elements.
* #throws ArrayStoreException - if the runtime type of the specified
* array is not a supertype of the runtime type of every element in this
* container.
* #throws NullPointerException if the specified array is null.
*/
public <E> E[] toArray(E[] array);
}
So you can't use an array of Object since you are storing Comparable. Instead, you need to use an array of Comparable.
smallArray = (T[]) new Object[len + 1];
should be
smallArray = (T[]) new Comparable[len + 1];

Calculator with batches of operations in java

Need to do a java calculator which works with batches. It must take an operation and then, for the next ones, just use the result of the previous operation as the first value of its new operation.
public class Calculator {
/**
* Public constructor of the calculator.
*/
**public Calculator () {/*...*/}**
/**
* Clean the internal state of the calculator
*/
**public void cleanOperations () { /*...*/ }**
/**
* Add a new operation to the internal state of the calculator.
* It is worth mentioning that the calculator behaves in an accumulative way ,
* thus only first operation has two operands.
* The rest of computations work with the accumulated value and only an extra
* new operand. Second input value must be ignored if the operation does not
* correspond to the first one.
*
* #param operation operation to add , as string , "+", "-", "*", "/".
* #param values Operands of the new operation (one or two operands ).
* Uses the varargs feature.
* https :// docs.oracle.com/javase /8/ docs/technotes/guides/language/varargs.html
* #throws IllegalArgumentException If the operation does not exist.
*/
**public void addOperation(String operation , float ... values) { /*...*/ }**
/**
* Execute the set of operations of the internal state of the calculator.
* Once execution is finished , internal state (operands and operations)
* is restored (EVEN if exception occurs ).
* This calculator works with "Batches" of operations.
* #return result of the execution
* #throws ArithmeticException If the operation returns an invalid value
* (division by zero)
*/
**public float executeOperations () { /*...*/ }**
/**
* Current internal state of calculator is printed
* FORMAT:
* "[{+/ -/"/"/*}] value1_value2 [{+/ -/"/"/*}] value1 [{+/ -/"/"/*}] value1 {...}"
* #return String of the internal state of the calculator
*/
#Override
public String toString () { /* ... */ }
}
SOME TEST IT SHOULD PASS:
// Add operations, calculate internal state representation (string pattern) and execute them as a single batch
calculator.addOperation("+", 4.5f, 6.8f);
calculator.addOperation("-", 3.1f);
calculator.addOperation("/", 6f);
assertEquals("[STATE:[+]4.5_6.8[-]3.1[/]6.0]", calculator.toString());
result = calculator.executeOperations();
assertEquals("[STATE:]", calculator.toString()); // state is restored
assertEquals(1.366f, result, EPSILON);//EPSILON = 0.01f
As you can see it must work by doing the first operation with 2 values but the next ones using the value stores from the one before and then execute with the operator and the value, the new operation.
Are you looking for this?
public class Calculator {
private String operation;
private float[] values;
private float answer;
/**
* Public constructor of the calculator.
*/
public Calculator() {
}
/**
* Clean the internal state of the calculator
*/
public void cleanOperations() {
operation = null;
values = null;
answer = 0;
}
/**
* Add a new operation to the internal state of the calculator.
* It is worth mentioning that the calculator behaves in an accumulative way ,
* thus only first operation has two operands.
* The rest of computations work with the accumulated value and only an extra
* new operand. Second input value must be ignored if the operation does not
* correspond to the first one.
*
* #param operation operation to add , as string , "+", "-", "*", "/".
* #param values Operands of the new operation (one or two operands ).
* Uses the varargs feature.
* https :// docs.oracle.com/javase /8/ docs/technotes/guides/language/varargs.html
* #throws IllegalArgumentException If the operation does not exist.
*/
public void addOperation(String operation, float... values) {
if (!(operation.equals("+") || operation.equals("-") || operation.equals("*") || operation.equals("/"))) {
throw new IllegalArgumentException(operation + " is not a valid operator. ( '+', '-', '*', '/')");
}
this.operation = operation;
this.values = values;
}
/**
* Execute the set of operations of the internal state of the calculator.
* Once execution is finished , internal state (operands and operations)
* is restored (EVEN if exception occurs ).
* This calculator works with "Batches" of operations.
*
* #return result of the execution
* #throws ArithmeticException If the operation returns an invalid value
* (division by zero)
*/
public float executeOperations() {
switch (operation) {
case "+":
if (values.length == 1) {
answer += values[0];
} else {
for (float value : values) {
answer += value;
}
}
break;
case "-":
if (values.length == 1) {
answer -= values[0];
} else if (values.length != 0) {
answer = values[0];
for (int i = 1; i < values.length; i++) {
answer -= values[i];
}
}
break;
case "*":
if (values.length == 1) {
answer *= values[0];
} else if (values.length != 0) {
answer = values[0];
for (int i = 1; i < values.length; i++) {
answer *= values[i];
}
}
break;
case "/":
if (values.length == 1) {
if (values[0] == 0) {
throw new ArithmeticException("Can not divide " + answer + " with " + values[0]);
}
answer /= values[0];
} else if (values.length != 0) {
answer = values[0];
for (int i = 1; i < values.length; i++) {
if (values[i] == 0) {
throw new ArithmeticException("Can not divide " + answer + " with " + values[i]);
}
answer /= values[i];
}
}
break;
}
return answer;
}
/**
* Current internal state of calculator is printed
* FORMAT:
* "[{+/ -/"/"/*}] value1_value2 [{+/ -/"/"/*}] value1 [{+/ -/"/"/*}] value1 {...}"
*
* #return String of the internal state of the calculator
*/
#Override
public String toString() {
StringBuilder string = new StringBuilder("values: [");
for (float value: values) {
string.append(value)
.append(" ")
.append(operation)
.append(" ");
}
string.append("] answer = ").append(answer);
return string.toString();
}
}

Forming a pattern of bits from a integer

I need help to design java code for generating bit array for any given integer in following manner:
23 should produce output as 1101011 (min length array)
explaination :
positions are given as 1 -2 4 -8 16 -32 ....
So 1101011 can be evaluated as:
1*1 + 1*-2 + 0*4+ 1*-8 + 0*16 +1*-32 + 1*64 = 23
This is the so-called negabinary representation of numbers (described first by Vittorio Grünwald in 1885). They can be encoded in a fashion very similar to the usual binary representation, just working with -2 instead of 2 as base (Java code inspired by C# code on https://en.wikipedia.org/wiki/Negative_base ):
class EncodeNegaBinary {
public static void main(String[] args) {
int n=0,input=0;
String result="";
final String[] BITS = { "0","1" };
if (args.length != 1) {
System.err.println("Please enter an integer to be converted");
return;
} else {
input = n = Integer.parseInt(args[0]);
}
while (n != 0) {
int r = n%-2;
n /= -2;
if (r == -1) {
r=1;
n++;
}
result = BITS[r] + result;
}
System.out.printf( "%d -> %s\n", input, result);
}
}
Since it is not usual int to binary conversion, at each step we need to consider two cases as at each position there can be only two choices 0 or 1. This is done recursively in the below program:
public class ModifiedIntToBinaryConversion{
public static int calcBinaryString(int reqSum, int currSum, int add, String bs) {
if (reqSum == currSum) { // base condtion 1
System.out.println("The string is \n" + bs);
return currSum;
}
if (add + currSum > reqSum) { // base condtion 2
return 0;
}
int newAdd = add * -2;
// System.out.println("new add is "+ newAdd +" currSum is "+ currSum);
int s1 = calcBinaryString(reqSum, currSum + add, newAdd, bs + "1");
if (s1 == reqSum)
return s1;
int s2 = calcBinaryString(reqSum, currSum, newAdd, bs + "0");
return s2;
}
public static void calcBinaryString(int sum) {
int s1 = calcBinaryString(sum, 0, 1, "");
if(s1 != sum) {
System.out.println("The binary equivalent couldn't be found");
}
}
public static void main(String[] args) {
calcBinaryString(23);
}
}
Now base condition 1 is clear as I am just checking whether required sum and calculated sum are equal.
For base condition 2, I will accept it's result of debugging and a bit of thought as I was getting Stackoverflow errors. Once the calculated sum becomes greater than the required sum and then we take the next -ve number so that it become less than req. sum. But then the next +ve number will be greater than the -ve number we just considered and thus the chances are very less that the calculated sum will ever be equal to req. sum.

Recursive print Factorial

So I did search and read abut every factorial listing on this site but I cannot seem to figure out what is wrong with my code. Iv tried multiple different return methods but they all keep failing. Any ideas?
public class RecursivelyPrintFactorial {
public static void printFactorial(int factCounter, int factValue) {
int nextCounter = 0;
int nextValue = 0;
if (factCounter == 0) // Base case: 0! = 1
System.out.println("1");
}
else if (factCounter == 1) // Base case: print 1 and result
System.out.println(factCounter + " = " + factValue);
}
else { // Recursive case
System.out.print(factCounter + " * ");
nextCounter = factCounter - 1;
nextValue = nextCounter * factValue;
}
return factValue * printFactorial(factValue - factCounter);
}
}
public static void main (String [] args) {
int userVal = 0;
userVal = 5;
System.out.print(userVal + "! = ");
printFactorial(userVal, userVal);
}
}
I have a feeling I have the equation incorrect in my return but iv tried every combination I can think of. Its driving me insane. Every one reports an error. Any ideas?
return factValue * printFactorial(factValue - factCounter);
I assume that you should be using the "next" values instead of these.
Edit: Also note that the function takes two parameters and is void. Returning factValue times void doesn't make sense.

How to access specific class?

Hi for one of my assignments I had to make an ackermann simulator in Java and I was having trouble. The assignment was to create three variations of the ackermann project, one regular, one recursive and one through a table lookup. well, I've done all that but the part that I'm struggling with is the creating a menu for it part. I'm not sure how to access each class when I select an option from the menu. do I need a main class for every single class or one for all of them? Here is my code and I guess my biggest question is how do I get user input when I select a version of the ackermann from the menu, thank you very much.
Here is my menu:
import java.util.Scanner;
public class AckMenu
{
public static void main(String [] args) throws InterruptedException
{
Scanner scan = new Scanner(System.in);
int choiceNumber = 0;
introduction();
while (choiceNumber != 4)
{
printMenuChoices();
choiceNumber = readChoiceNumber();
switch (choiceNumber)
{
case 1:
//
AckermannValue.Ack(3,3);
break;
case 2:
AckermannTrace.Ack(1,3);
break;
case 3:
AckermannTableLookup.getValue();
break;
default:
System.out.println("The game is over.");
choiceNumber = 4;
break;
}//switch
}//while
}
private static void introduction()
{
System.out.println("\n\n" +
" This program allows you to call the Ackermann function.");
System.out.println("\n\n" + "Please choose one of the versions of the Ackermann function.");
}
private static void printMenuChoices()
{
System.out.println(""+
"1) Ackermann Value.\n"+
"2) Ackermann Trace.\n"+
"3) Ackermann Table Lookup.\n"+
"4) Quit.");
}
private static int readChoiceNumber()
{
Scanner scan = new Scanner(System.in);
int choiceNumber;
String indent = " ";
System.out.println("please enter the number of the method you want to call");
choiceNumber = scan.nextInt();
while(choiceNumber < 1 || choiceNumber > 4)
{
System.out.println(indent + "the number must be 1 through 4");
System.out.println(indent + " please enter a proper choice. ");
choiceNumber = scan.nextInt();
}
return choiceNumber;
}
}
and my 3 methods, first the regular version with no recursion.
import java.util.Scanner;
public class AckermannValue {
//public static void AckMethod() throws InterruptedException {
//static int count = 0;
public static int Ack(int m, int n) {
if (m < 0 || n < 0) {
throw new IllegalArgumentException("Non-negative args only!");
}
if (m == 0)
{
//count++;
//System.out.println("count: " + count + " M: " + m + " N: " + n);
return n + 1;
}
else if (n == 0)
{
//count++;
// System.out.println("count: " + count + " M: " + m + " N: " + n);
return Ack(m-1, 1);
}
else {
//count++;
//System.out.println("count: " + count + " M: " + m + " N: " + n);
return Ack(m-1, Ack(m,n-1));
}
}
//public static void main (String args [] ) {
//System.out.println(Ack(3,7));
//}
}
//}
Recursive method
import java.util.Scanner;
public class AckermannTrace {
static int count = 0;
public static int Ack(int m, int n) {
if (m < 0 || n < 0) {
throw new IllegalArgumentException("Non-negative args only!");
}
if (m == 0)
{
count++;
System.out.println("count: " + count + " M: " + m + " N: " + n);
return n + 1;
}
else if (n == 0)
{
count++;
System.out.println("count: " + count + " M: " + m + " N: " + n);
return Ack(m-1, 1);
}
else {
count++;
System.out.println("count: " + count + " M: " + m + " N: " + n);
return Ack(m-1, Ack(m,n-1));
}
}
//public static void main (String args [] ) {
//System.out.println(Ack(3,7));
//}
}
The table lookup version of the ackermann
import java.util.Hashtable;
public class AckermannTableLookup {
/**
* The table containing the values of <i>Ackermann</i>'s function.
*/
private Hashtable<Integer, Hashtable<Integer, Integer>> table;
/**
* Constructs a new table, computing all values of <i>Ackermann</i>'s
* function <i>A(i, j)</i> that are <i>n</i> or less.
*
* #param n
* the maximum value of the new table
*/
public void AckermannTable(int n) {
// construct new table
table = new Hashtable<Integer, Hashtable<Integer, Integer>>();
// set first value
int i = 1;
int j = 2;
setValue(1, 1, 2);
while (true) {
int newValue = -1;
// compute next entry
if (i == 1) {
newValue = getValue(i, j - 1) * 2;
} else {
newValue = getValue(i - 1, getValue(i, j - 1));
}
if (newValue > n || newValue == -1) {
if (j == 1) {
// no single entry in this row - return
return;
} else {
// go to the next row
i++;
j = 1;
}
} else {
// save the computed value
setValue(i, j, newValue);
j++;
}
}
}
/**
* Returns the value of <i>Ackermann</i>'s function <i>A(i, j)</i>, if it
* is <i>n</i> or less, and <code>-1</code> otherwise.
*
* #param i
* the first parameter for <i>Ackermann</i>'s function
* #param j
* the second parameter for <i>Ackermann</i>'s function
* #return
* <i>A(i, j)</i>
*/
public int getValue(int i, int j) {
if (j == 0) {
return 2;
} else {
if (table.containsKey(i)) {
Hashtable<Integer, Integer> rowI = table.get(i);
if (rowI.containsKey(j)) {
return rowI.get(j);
} else {
return -1;
}
} else {
return -1;
}
}
}
/**
* Returns the inverse value of <i>Ackermann</i>'s function <i>A(m, n)</i>.
*
* #param m
* the first parameter for the inverse <i>Ackermann</i>'s function
* #param n
* the second parameter for the inverse <i>Ackermann</i>'s function
* #return
* the inverse of <i>A(m, n)</i>
*/
public int getInverse(int m, int n) {
if (n >= 4) {
int j = 0;
while (2 * getValue(m, j) <= n && getValue(m, j) != -1) {
j++;
}
return j - 1;
} else if (m >= n) {
int i = 1;
while (getValue(i, (int)Math.floor(m / n)) != -1) {
i++;
}
return i;
}
return -1;
}
/**
* Adds the passed value of <i>Ackermann</i>'s function <i>A(i, j)</i> to
* this table.
*
* #param i
* the first parameter for <i>Ackermann</i>'s function
* #param j
* the second parameter for <i>Ackermann</i>'s function
* #param value
* <i>A(i, j)</i>
*/
private void setValue(int i, int j, int value) {
if (!table.containsKey(i)) {
table.put(i, new Hashtable<Integer, Integer>());
}
Hashtable<Integer, Integer> rowI = table.get(i);
rowI.put(j, value);
}
}
Make sure all your classes are in the same package.
Then either make all your methods static to call them by their class names(in your lookup table class) OR
You just need to modify your switch statement.
Don't call the Ack by its classname. First create an object of its class and then call that function. For example in case1 :
AckermannValue object1 = new AckermannValue();
object1.Ack(3,3);
Now your program will run fine.

Categories