gpt4 book ai didi

java - 符号库设计模式

转载 作者:行者123 更新时间:2023-11-30 04:04:24 26 4
gpt4 key购买 nike

我正在构建一个用于符号计算的java库。我创建了一个抽象表达式类,用于在乘积、分数和多项式之间进行各种运算。然而,当我想添加地板和天花板时,事情变得复杂了。据我所知,周围有这样的库,我想知道是否有可以遵循的特定设计模式,或者是否有任何资源可以寻找灵感和指导。

最佳答案

您正在做的很可能是解析“上下文无关语言”(根据 Chomsky hierarchy 的 Type-2)。尝试阅读http://en.wikipedia.org/wiki/LL_parserhttp://en.wikipedia.org/wiki/Pushdown_automaton - 你不一定要理解背后的数学原理,但它会给你线索。

我同意你的观点,复合设计模式对于表达式的对象表示非常有用。以下示例来 self 的代码,其目的是保存并打印一个表达式,但您可以轻松修改它以捕捉这个想法。

表达式是根对象。它有诸如CompoundExpression、Number、Variable 等后代。

public interface Expression {
/**
* @return a numeric value of the expression
*/
double getValue();

/**
* @return a string representation of the expression
*/
String getExpression();

/**
* @return true if the expression is an atomic expression
*/
boolean isLeaf();
}

CompoundExpression 是一个操作作为其操作数的容器。

public class CompoundExpression implements Expression {

/**
* Creates a compound expression.
* @param operation the specified operation
* @param operands The specified operands. The amount of operands must exactly
* match the arity of the operation.
*/
public CompoundExpression(Operation operation, Expression ... operands) {
super();
this.operands = Arrays.asList(operands);
this.operation = operation;
}

/**
* The expressions which this expression is compound of ;)
*/
final private List<Expression> operands;

/**
* The operation on operands.
*/
final private Operation operation;

/**
* {@inheritDoc}
*/
@Override
public String getExpression() {
return this.operation.compose(this.operands);
}

/**
* {@inheritDoc}
*/
@Override
public double getValue() {
return this.operation.calculate(this.operands);
}

/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
....
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
....
}

/**
* {@inheritDoc}
*/
@Override
public boolean isLeaf() {
return false;
}
}

数字是一片叶子。您可以实现更多类型的叶子,例如变量。

public class Number implements Expression {

/**
* Creates an atomic expression with the specified value.
* @param value the numeric value
*/
public Number(double value) {
super();
this.value = value;
}

/**
* The numeric value of the number.
*/
private double value;

/**
* {@inheritDoc}
*/
@Override
public String getExpression() {
return String.valueOf(this.value);
}

/**
* {@inheritDoc}
*/
@Override
public double getValue() {
return this.value;
}

/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
....
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
....
}

/**
* {@inheritDoc}
*/
@Override
public boolean isLeaf() {
return true;
}
}

操作保存操作,例如 Plus、Sinus、Floor、Ceiling...如果需要,它还可能具有实际计算值的能力。

public interface Operation {

/**
* Returns a numeric value of the operation performed on the given operands.
*
* @param operands the list of operands
* @return a numeric value of the operation
*/
double calculate(List<Expression> operands);

/**
* Returns a string representation of the operation performed on the given operands.
* @param operands operands the list of operands
* @return a string representation of the operation
*/
String compose(List<Expression> operands);

/**
* Returns a string representation of the operator
* @return string representation of the operator
*/
String getOperator();
}

BinaryOperation 是所有二元运算的父级。它不一定需要,但有它很方便。

public abstract class BinaryOperation implements Operation {

/**
* {@inheritDoc}
*/
@Override
public String compose(List<Expression> operands) {
assert (operands.size() == 2);

final Expression op1 = operands.get(0);
final Expression op2 = operands.get(1);
final boolean op1Leaf = op1.isLeaf();
final boolean op2Leaf = op2.isLeaf();
final StringBuilder builder = new StringBuilder();
if (!op1Leaf) {
builder.append("(");
}
builder.append(op1.getExpression());
if (!op1Leaf) {
builder.append(")");
}
builder.append(this.getOperator());
if (!op2Leaf) {
builder.append("(");
}
builder.append(op2.getExpression());
if (!op2Leaf) {
builder.append(")");
}
return builder.toString();
}
}

二元运算的示例:

public class PlusOperation extends BinaryOperation {

/**
* {@inheritDoc}
*/
@Override
public double calculate(List<Expression> operands) {
assert (operands.size() == 2);
return operands.get(0).getValue() + operands.get(1).getValue();
}

/**
* {@inheritDoc}
*/
@Override
public String getOperator() {
return "+";
}

}

UnaryOperation 是所有一元运算的父级。它不一定需要,但有它很方便。

public abstract class UnaryOperation implements Operation {

/**
* {@inheritDoc}
*/
@Override
public String compose(List<Expression> operands) {
assert (operands.size() == 1);
return this.getOperator() + "(" + operands.get(0).getExpression() + ")";
}

}

一元运算的示例:

public class CosinusOperation extends UnaryOperation {

/**
* {@inheritDoc}
*/
@Override
public double calculate(List<Expression> operands) {
assert (operands.size() == 1);
return Math.cos(operands.get(0).getValue());
}

/**
* {@inheritDoc}
*/
@Override
public String getOperator() {
return "cos";
}
}

如何使用它们。您可以“手动”创建如下表达式:

Expression exp = new CompoundExpression(
new PlusOperation(),
new CompoundExpression(
new DivisionOperation(),
new CompoundExpression(
new PlusOperation(),
new Number(2),
new Number(3)
),
new Number(4)
),
);

并且您必须使用下推自动机的实现来创建表达式:)

关于java - 符号库设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21111027/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com