7
我應該實現一個包含數學表達式的二叉樹,對每個二元或一元表達式使用不同的類。例如: :數學表達式二叉樹
Expression e = new Sin(
new Pow(
new Mul(
new Plus(
new Mul(new Num(2), new Var("x")),
new Var("y")),
new Num(4)),
new Var("x")));
樹的葉子可以是變量或數字。每個變量可以轉換爲另一個表達式與方法:
Expression assign(String var, Expression expression)
我有2個抽象類的一元和二元運算符。
我一直遇到困難,弄清楚如何將相同的表達式賦值給表達式本身的變量之一。例如:
Expression e1 = new Plus(1,"x");
e1.assign("x", e1);
System.out.println(e1.toString());
輸出應該是:
((x+1)+1)
什麼實際發生的是,表達式的左側部分本身指向這會導致一個無限循環。有沒有辦法使對象重複,但用不同的指針來避免它?或者,也許採用不同的方式來實現「分配」方法的工作方式?
這是我實現:
BinaryExpression類:
import java.util.List;
import java.util.Map;
abstract public class BinaryExpression extends BaseExpression implements Expression {
protected Expression first, second;
public BinaryExpression(Expression first, Expression second) {
this.setSecond(second);
this.setFirst(first);
}
public BinaryExpression(double number1, double number2) {
this(new Num(number1), new Num(number2));
}
public BinaryExpression(double number, String variable) {
this(new Num(number), new Var(variable));
}
public BinaryExpression(String variable, double number) {
this(new Var(variable), new Num(number));
}
public BinaryExpression(String variable1, String variable2) {
this(new Var(variable1), new Var(variable2));
}
public BinaryExpression(Expression expression, String variable) {
this(expression , new Var(variable));
}
public BinaryExpression(double number, Expression expression) {
this(new Num(number), expression);
}
public BinaryExpression(Expression expression, double number) {
this(expression, new Num(number));
}
public BinaryExpression(String variable, Expression expression) {
this(new Var(variable), expression);
}
public Expression getSecond() {
return second;
}
public void setSecond(Expression second) {
this.second = second;
}
public Expression getFirst() {
return first;
}
public void setFirst(Expression first) {
this.first = first;
}
public double evaluate(Map<String, Double> assignment) throws Exception {
try {
return operate(first.evaluate(assignment), second.evaluate(assignment));
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
abstract public double operate(double first, double second) throws Exception;
public List<String> getVariables() {
java.util.List<String> firstList, secondList;
firstList = this.first.getVariables();
secondList = this.second.getVariables();
for (int i = 0; i < secondList.size(); i++) {
boolean seen = false;
for (int j = 0; j < firstList.size(); j++) {
if (((String) firstList.get(j)).equals((String) secondList.get(i))) {
seen = true;
break;
}
}
if (!seen) {
firstList.add(secondList.get(i));
}
}
return firstList;
}
public Expression assign(String var, Expression expression) {
this.first = first.assign(var, expression);
this.second = second.assign(var, expression);
return this;
}
abstract public String operator();
public String toString() {
return "(" + this.first.toString() +
this.operator() +
this.second.toString() + ")";
}
}
變量類:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Var implements Expression {
private String variable;
/**
* setting the desired variable.
* @param variable the variable to set
*/
public Var(String variable) {
this.variable = variable;
}
/**
* getting the variable string.
* @return the variable string
*/
public String getVariable() {
return variable;
}
/**
* setting the variable string.
* @param newVariable the string we want to set.
*/
public void setVariable(String newVariable) {
this.variable = newVariable;
}
@Override
public double evaluate(Map<String, Double> assignment) throws Exception {
if (assignment.containsKey(this.variable)) {
return assignment.get(this.variable);
} else {
throw new Exception("variable wasn't assigned");
}
}
@Override
public double evaluate() throws Exception {
throw new Exception("variable wasn't assigned");
}
@Override
public List<String> getVariables() {
java.util.List<String> singleVariable = new ArrayList<String>();
singleVariable.add(this.variable);
return singleVariable;
}
@Override
public Expression assign(String var, Expression expression) {
if (var.equals(this.variable)) {
return expression;
} else {
return this;
}
}
public String toString() {
return this.variable;
}
}
Number類:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Num implements Expression {
private double value;
/**
* creating a new number.
* @param number the value to set.
*/
public Num(double number) {
this.setValue(number);
}
/**
* getting the number's value.
* @return the value to set.
*/
public double getValue() {
return value;
}
/**
* setting a new number.
* @param newValue the number to set.
*/
public void setValue(double newValue) {
this.value = newValue;
}
@Override
public double evaluate(Map<String, Double> assignment) {
return getValue();
}
@Override
public double evaluate() {
return getValue();
}
@Override
public List<String> getVariables() {
java.util.List<String> emptyList = new ArrayList<String>();
return emptyList;
}
@Override
public Expression assign(String var, Expression expression) {
return this;
}
public String toString() {
return Double.toString(this.value);
}
}
任何形式的幫助是apprec iated。
我在這裏將我得到的錯誤:
Exception in thread "main" java.lang.StackOverflowError
at sun.misc.FloatingDecimal$BinaryToASCIIBuffer.dtoa(Unknown Source)
at sun.misc.FloatingDecimal$BinaryToASCIIBuffer.access$100(Unknown Source)
at sun.misc.FloatingDecimal.getBinaryToASCIIConverter(Unknown Source)
at sun.misc.FloatingDecimal.getBinaryToASCIIConverter(Unknown Source)
at sun.misc.FloatingDecimal.toJavaFormatString(Unknown Source)
at java.lang.Double.toString(Unknown Source)
at Num.toString(Num.java:50)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)
at BinaryExpression.toString(BinaryExpression.java:94)
at BinaryExpression.toString(BinaryExpression.java:96)...
這裏還是要在加類的clone方法的例子:
public Expression clone() {
Expression newFirst = this.first, newSecond = this.second;
return new Plus(newFirst, newSecond);
}
我試圖通過改變使用它分配的無功方法是這樣的:
public Expression assign(String var, Expression expression) {
if (var.equals(this.variable)) {
return expression.clone();
} else {
return this;
}
}
此外我還試圖通過改變分配甲基修復它OD這種方式改變VAR方法之後並沒有使用其他的功能的工作:
public Expression assignHelp(String var, Expression expression) {
this.first = first.assignHelp(var, expression);
this.second = second.assignHelp(var, expression);
return this;
}
public Expression assign(String var, Expression expression) {
return assignHelp(var, expression.clone());
}
爲什麼你需要一個賦值方法而不只是建立一個新的表達方式? – fdsa
如果Expression實現Clonable,則可以調用expression.clone()。 –
我試圖通過這種方式爲每個類的克隆方法: 表達式克隆(){ 返回新的表達式(this.first,this.second); } 並在var類reurning expression.clone()中的assign方法,但它不工作,我不知道爲什麼。 – Ryan