C
So konnte das Problem lösen. Hier der komplette richtig funktionierende Code:
package de.hsfulda.dua.stackcalculator;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Umsetzung eines Taschenrechners mit zwei Stacks.
* Es werden die vier Grundrechenarten unterstützt.
*/
/*
* Add your personal information here. Missing or incorrect information
* will lead to the ignoring of this solution.
*/
@Author(name = "Gies",
vorname = "Christopher",
matrikelNr = "529685",
mailAddress = "christopher.gies@googlemail.com")
public class StackCalculator
{
HashMap<String,Integer> priority;
private ArrayListStack<Double> operanden;
private ArrayListStack<String> operatoren;
ArrayList<String> strFormula;
int index;
/**
* versetzt den StackCalculator in einen gültigen Ausgangszustand
*/
public StackCalculator()
{
priority = new HashMap<String,Integer>();
priority.put("+", 0);
priority.put("-", 0);
priority.put("*", 1);
priority.put("/", 1);
operanden = new ArrayListStack<Double>();
operatoren = new ArrayListStack<String>();
}
/**
* Berechnung der übergebenen Formel
*
* @param formula Formel als String
* @return double Ergebnis der Formel
*/
public double calculate (String formula)
{
// System.out.println(operanden.size());
// System.out.println(operatoren.size());
System.out.println("Zu Berechnende Formel: " + formula);
strFormula = formatString(formula);
// System.out.println(strFormula.size());
// System.out.println("---" + strFormula.get(0) + "---");
// System.out.println("---" + strFormula.get(1) + "---");
/* fängt den Fehler ab, der entsteht wenn die Methode stringFormat mit nur einem Operator aufgerufen wird:
* Die Methode liefert dann eine ArrayList mit size=2, an index 0 hält die ArrayList einen leeren String
* und erst an index 1 steht der String der den Operator enthält. Der Fehler liegt denke ich an der internen
* Verarbeitung der split Methode in formatString.
* Außerdem werden die ungewollten Eingaben abgefangen, wenn dem Programm z.B. ein String mit nur einem Operator,
* einem Operanden, einem Leerzeichen oder ein komplett leerer String übergeben wird.*/
if(strFormula.size() == 2 )
{
strFormula.remove(0);
if(priority.containsKey(strFormula.get(0)))
System.out.println("Ergebnis: 0");
return 0;
}else if(strFormula.size() == 1)
{
if(strFormula.get(0) == "" || strFormula.get(0) == " ")
{
System.out.println("Ergebnis: 0");
return 0;
}
else{
System.out.println("Ergebnis: " + Double.parseDouble(strFormula.get(0)));
return Double.parseDouble(strFormula.get(0));
}
}
/* pushed die ersten 3 Elemente der Gleichung in die entsprechenden Stacks */
operanden.push(Double.parseDouble(strFormula.get(0)));
operatoren.push(strFormula.get(1));
operanden.push(Double.parseDouble(strFormula.get(2)));
index = 2;
/* Schleifen- bzw. Abfragenkonstrukt, dass über die interne Stackabarbeitung und die Entscheidung,
* sind noch Elemente zu berechnen und in welcher Reihenfolge verfügt.*/
do
{
// System.out.println("Oberstes Element im OperandenStack: " + operanden.top());
// System.out.println("Elemente im OperandenStack: " + operanden.size());
// System.out.println("Oberstes Element im OperatorenStack: " + operatoren.top());
// System.out.println("Elemente im OperatorenStack: " + operatoren.size());
while(operatoren.size() > 0 && hasNext() && checkPriority(nextOperator()))
{
operanden.push(calculateOneOperation(operanden.pop(), operatoren.pop(), operanden.pop()));
}
if(hasNext())
pushNext();
}while(hasNext());
while(operatoren.size() > 0)
{
operanden.push(calculateOneOperation(operanden.pop(), operatoren.pop(), operanden.pop()));
// System.out.println(operatoren.size());
}
// System.out.println("Elemente im OperandenStack: " + operanden.size());
// System.out.println("Elemente im OperatorenStack: " + operatoren.size());
System.out.println("Ergebnis: " + operanden.top());
return operanden.pop();
}
/**
* prüft die Präzedenz zweier Operatoren
* @param String operator nächster zu prüfender Operator
* @return boolean true wenn die Präzedenz des Operators im Stack höher ist als die des Vergleichsoperators
* */
public boolean checkPriority(String operator)
{
// System.out.println(operator);
// System.out.println(operatoren.top());
if(priority.get(operator) <= priority.get(operatoren.top()))
return true;
else
return false;
}
/**
* Gibt den nächsten Operatoren im String zurück
* @return String nächster Operator im String
*/
public String nextOperator()
{
// System.out.println(strFormula.get(index + 1));
return strFormula.get(index + 1);
}
/**
* pushed den nächsten Operator und den nächsten Operanden in die entsprechenden Stacks
*/
public void pushNext()
{
index++;
operatoren.push(strFormula.get(index));
index++;
operanden.push(Double.parseDouble(strFormula.get(index)));
}
/**
* prüft ob noch weiter Elemente im String abzuarbeiten sind
* @return boolean true wenn noch ein Element abzuarbeiten
*/
public boolean hasNext()
{
// System.out.println(strFormula.size());
// System.out.println(index);
if(strFormula.size() > index + 1)
return true;
else
return false;
}
/**
* Führt die Berechnung einer Operation bestehend aus 2 Operanden und einem Operator durch
* @param operand1
* @param operator
* @param operand2
* @return double Ergebnis der Berechnung
* @throws IllegalArgumentException
*/
public double calculateOneOperation(double operand1, String operator, double operand2) throws IllegalArgumentException
{
if(operator.equals("+"))
{
double result = operand2 + operand1;
// System.out.println(result);
return result;
}
else if(operator.equals("-"))
{
double result = operand2 - operand1;
// System.out.println(result);
return result;
}
else if(operator.equals("*"))
{
double result = operand2 * operand1;
// System.out.println(result);
return result;
}
else if(operator.equals("/"))
{
double result = operand2 / operand1;
// System.out.println(result);
return result;
}
else
throw new IllegalArgumentException("Es wurde bei der Berechnung einer Operation ein nicht erlaubter Operator gefunden!");
}
/**
* Formatiert den übergebenen String und bereitet ihn damit für die Abarbeitung in der Methode calculate vor.
* @param String formula zu formatierender String
* @return ArrayList<String> die die Operatoren und Operanden der Gleichung in entsprechender Reihenfolge hält.
*/
public ArrayList<String> formatString(String formula)
{
ArrayList<String> liste = new ArrayList<String>();
ArrayList<Character> buffer = new ArrayList<Character>();
String[] stringBuffer;
/* bereitet String vor indem alle Leerzeichen entfernt werden wenn welche vorhanden sind */
formula = formula.replaceAll(" ", "");
/* Schreibt jeden Buchstaben des Strings an eine Positions der ArrayList */
for(int i = 0; i < (formula.length()); i++)
{
buffer.add(formula.charAt(i));
}
/* fügt Leerzeichen vor und nach allen Operatoren ein */
for(int i = 0; i < (buffer.size()); i++)
{
if(buffer.get(i) == '+' || buffer.get(i) == '-' || buffer.get(i) == '*' || buffer.get(i) == '/')
{
buffer.add(i, ' ');
buffer.add(i + 2, ' ');
i++;
}
}
formula = "";
/* konvertiert ArrayList wieder in einen String */
for(char letter : buffer)
{
formula += letter;
}
stringBuffer = formula.split(" ");
for(String str : stringBuffer)
{
liste.add(str);
// System.out.println(str);
}
return liste;
}
public static void main (String[] args)
{
StackCalculator test1 = new StackCalculator();
// test1.calculateOneOperation(1,"+",2);
// String helfer= "8+12-14*1*103";
String helfer= " ";
// String helfer1= "12-4";
// test1.stringFormat(helfer);
test1.calculate(helfer);
// test1.calculate(helfer1);
}
}