Hallo,
ist jetzt zwar schon ne Weile her, aber ich wollte noch den Quellcode nachreichen. Vielleicht hat jemand ja mal n ähnliches Problem:
Hauptklasse Calculator mit Main-Methode:
Klasse Memory:
Klasse Verwalter (Ja, Operator o.ä. wäre besser gewesen, aber Operation und Operator war leicht verwirrend beim Arbeiten und Auswerten...)
Interface Operation:
Rechenoperation am Beispiel Addition:
ist jetzt zwar schon ne Weile her, aber ich wollte noch den Quellcode nachreichen. Vielleicht hat jemand ja mal n ähnliches Problem:
Hauptklasse Calculator mit Main-Methode:
Java:
package calculator;
import java.util.EmptyStackException;
import java.util.Scanner;
public class Calculator {
static Scanner in = new Scanner(System.in);
private static Memory calcMemory = new Memory();
private static Verwalter calcVerwalter = new Verwalter();
private void saveInStack(double userInput, Memory calcMemory) {
calcMemory.push(userInput);
}
public static void main(String[] args) throws EmptyStackException {
Calculator calc = new Calculator();
registerAllOperations(calcVerwalter);
// Eingabe von Konsole an Memory
while (true) {
if (calcMemory.isEmpty()) {
System.out.println("Der Speicher ist leer. Bitte geben Sie eine Zahl ein.");
}
System.out.println("Eingabe: ");
String userInput = in.next();
executeInput(userInput, calc, calcVerwalter, calcMemory);
System.out.println("Stack [" + calcMemory.toString() + "]");
System.out.println("");
}
}
static Memory executeInput(String userInput, Calculator calc, Verwalter verwalter, Memory calcMemory) {
//Cache, um bei EmptyStackException die erste Eingabe wiederherzustellen.
Double[] dump = calcMemory.dumpStack();
try {
Double numberInput = Double.parseDouble(userInput);
calc.saveInStack(numberInput, calcMemory);
} catch (NumberFormatException e) {
try {
String symbolInput = userInput;
verwalter.executeOperation(symbolInput, calcMemory);
} catch (EmptyStackException a) {
//Exception, wenn Rechenoperation weitere Werte benötigt
System.out
.println("Die letzte Rechenoperation benötigt mehr Werte. Bitte geben Sie eine weitere Zahl ein.");
calcMemory.restoreStack(dump);
}
}
return calcMemory;
}
static void registerAllOperations(Verwalter verwalter) {
//Registrieren aller möglichen Rechenoperationen
verwalter.register(new Addition());
verwalter.register(new Division());
verwalter.register(new Multiplication());
verwalter.register(new Potency());
verwalter.register(new Square());
verwalter.register(new SquareRoot());
verwalter.register(new Subtraction());
verwalter.register(new TopAverage());
verwalter.register(new TopSum());
}
}
Klasse Memory:
Java:
package calculator;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.*;
public class Memory {
private Stack<Double> calcMemory = new Stack<Double>();
void push(double numIn) {
calcMemory.push(numIn);
}
double pop() {
double numOut = calcMemory.pop();
return numOut;
}
@Override
public String toString() {
String output = "";
for (int i = 0; i < calcMemory.size(); i++) {
output += formatNumber(calcMemory.elementAt(i));
if (i != calcMemory.size() - 1) {
output += " | ";
}
}
return output;
}
boolean isEmpty() {
if (!calcMemory.isEmpty()) {
return false;
}
return true;
}
int size() {
return calcMemory.size();
}
//dump to reset memory in case of invalid user input
Double[] dumpStack() {
Double[] content = calcMemory.toArray(new Double[0]);
return content;
}
void restoreStack(Double[] dump) {
calcMemory.clear();
for (Double d : dump) {
calcMemory.push(d);
}
}
// Nachkommastellen
private static String formatNumber(double number) {
/* always use German decimal formatter symbols (, and .) */
DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.GERMANY);
NumberFormat formatter = new DecimalFormat("#0.####", decimalFormatSymbols);
return formatter.format(number);
}
}
Klasse Verwalter (Ja, Operator o.ä. wäre besser gewesen, aber Operation und Operator war leicht verwirrend beim Arbeiten und Auswerten...)
Java:
package calculator;
import java.util.ArrayList;
import java.util.List;
public class Verwalter {
private List<Operation> registered = new ArrayList<Operation>();
void register(Operation o) {
registered.add(o);
}
boolean isRegistered(Operation o) {
return registered.contains(o);
}
void executeOperation(String symbolToSearch, Memory stack) {
for (int i = 0; i < registered.size(); i++) {
Operation search = registered.get(i);
if (search.isMatchingSymbol(symbolToSearch)) {
search.calculate(stack);
}
}
}
}
Interface Operation:
Java:
package calculator;
public interface Operation {
public void calculate(Memory stack);
public boolean isMatchingSymbol(String userInputSymbol);
}
Rechenoperation am Beispiel Addition:
Java:
package calculator;
public class Addition implements Operation {
public void calculate(Memory stack) {
double sub1 = stack.pop();
double sub2 = stack.pop();
stack.push(sub1 + sub2);
}
@Override
public boolean isMatchingSymbol(String userInputSymbol) {
return userInputSymbol.equals("+");
}
}