Ich habe ein Problem! Kann ich in den Stack keine double Werte einlesen?
Wir müssen in der Schule so nen UPN-Taschenrechner machen und dafür benötigt man nen Stack!
UPN = umgekehrt polnische Notation
Und wenn ich meinen Stack füllen will dann kommt immer irgendwas mit nicht gültig für double aber wie soll ich sonst die Zahlen für den Rechner einlesen?
Vielleicht hat ja einer von euch ne idee bzw. hatte das Problem auch schon!!!
ich bin mir nicht ganz sicher, was du meinst.
Ich nehme an, dass du die Klasse java.util.Stack verwendest.
Diese hat eine push- und eine pop-Methode. Die push-Methode übernimmt
ein Objekt vom Typ Object. Da double ein primitiver Datentyp ist musst du
die Wrapper-Klassen verwenden. Für jeden primitiven Datentyp gibt es eine.
Integer, Double, Boolean, Character ...
Code:
Double aDoubleObj = new Double(3.45);
Stack stack = new Stack();
stack.push(aDoubleObj);
Die double-Werte bekommst du dann über die peek- oder pop-Methode zurück.
peek gibt dir das oberste Objekt auf dem Stack zurück. Dieses bleibt allerdings
auf dem Stack liegen. pop gibt dir auch das oberste Objekt zurück. Löscht es aber
vom Stack. Da die Methoden jeweils ein Object zurückgeben, musst du casten.
Code:
Double d = (Double) stack.pop(); // downcast in Double
double doubleValue = d.doubleValue();
Hier noch ein netter kleiner Taschenrechner von mir. Vielleicht hilft es
dir weiter oder zeigt dir neue Wege.
Code:
import java.io.*;
import java.util.*;
public class Calculator {
private String formula;
private Stack numberStack = new Stack();
public static final int NONE_OPERATOR = -1;
public static final int PLUS_OPERATOR = 0;
public static final int MINUS_OPERATOR = 1;
public static final int MUL_OPERATOR = 2;
public static final int DIV_OPERATOR = 3;
public Calculator(String formula) {
this.formula = formula;
}
public double calculate() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
this.infixToPostfix(new ByteArrayInputStream(this.formula.getBytes()),
bout);
StringTokenizer tok = new StringTokenizer(bout.toString());
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (operatorTyp(token) == Calculator.NONE_OPERATOR) {
this.numberStack.push(Double.valueOf(token));
}
else {
Number result = null;
Number op2 = (Number)this.numberStack.pop();
Number op1 = (Number)this.numberStack.pop();
switch (operatorTyp(token)) {
case Calculator.PLUS_OPERATOR:
result = new Double(op1.doubleValue() + op2.doubleValue());
break;
case Calculator.MINUS_OPERATOR:
result = new Double(op1.doubleValue() - op2.doubleValue());
break;
case Calculator.MUL_OPERATOR:
result = new Double(op1.doubleValue() * op2.doubleValue());
break;
case Calculator.DIV_OPERATOR:
result = new Double(op1.doubleValue() / op2.doubleValue());
break;
}
this.numberStack.push(result);
}
}
}
catch (IOException ex) {
throw new RuntimeException("can't calculate because of internal errors.");
}
return ( (Number)this.numberStack.pop()).doubleValue();
}
private int operatorTyp(String str) {
if (str.equals("+"))
return Calculator.PLUS_OPERATOR;
if (str.equals("-"))
return Calculator.MINUS_OPERATOR;
if (str.equals("*"))
return Calculator.MUL_OPERATOR;
if (str.equals("/"))
return Calculator.DIV_OPERATOR;
return Calculator.NONE_OPERATOR;
}
public void infixToPostfix(InputStream infix, OutputStream postfix) throws
IOException {
Stack opStack = new Stack();
StreamTokenizer infixTok = new StreamTokenizer(infix);
PrintWriter postfixOut = new PrintWriter(postfix, true);
int tokTyp = 0;
String operator;
String token;
boolean pushed;
infixTok.wordChars('0', '9');
infixTok.ordinaryChar('+');
infixTok.ordinaryChar('-');
infixTok.ordinaryChar('*');
infixTok.ordinaryChar('/');
while ( (tokTyp = infixTok.nextToken()) != StreamTokenizer.TT_EOF) {
pushed = false;
if (operatorTyp(operator = Character.toString( (char) infixTok.ttype)) !=
Calculator.NONE_OPERATOR) {
token = operator;
while (!pushed) {
if (token.equals("+") || token.equals("-")) {
if (opStack.isEmpty()) {
opStack.push(token);
pushed = true;
}
else
postfixOut.print(" " + opStack.pop());
}
else if (token.equals("*") || token.equals("/")) {
if (opStack.isEmpty()) {
opStack.push(token);
pushed = true;
}
else {
String op = (String) opStack.peek();
if (op.equals("+") || op.equals("-")) {
opStack.push(token);
pushed = true;
}
else
postfixOut.print(" " + opStack.pop());
}
}
}
}
else
postfixOut.print(" " + Double.toString(infixTok.nval));
}
while (!opStack.isEmpty()) {
postfixOut.print(" " + opStack.pop());
}
postfixOut.flush();
}
public static void main(String[] args) {
Calculator calc = new Calculator("23+12+3*23/2");
System.out.println("Result: " + calc.calculate());
}
}
wenn es eine vereinfachte version sein soll gehts auch einfacher:
erstelle zb 4 variablen, dann ist die speicherung halt auf 4 einträge begrenzt.
sowas mussten wir auch mal in der schule machen und das ziel ist den aufbau des stacks zu verstehen und dazu hilft die variante mit dem selbst erstelltem minimiertem stack mehr, als die vorgefertigte klasse zu nutzen