我正在处理中编写一个转换复数的程序。但是,我想要一种获取输入字符串并使用复变量计算转换的方法。例如:
1/(z+1)
(z^2)/(z/2)
其中 z 是复数。现在,我查看了 JEP 和一些示例,但我无法确定它是否允许您实际输入 z 作为变量(并且在任何情况下它都不是免费的)。是否有用于 Java 的表达式解析器(在处理中工作,它使用旧版本的 java 并且没有泛型)我可以用来执行此操作?
如果没有,有人可以指出如何创建一个的基础知识吗?
正如 PhiLo 所提到的,您可以使用泛型。试试这个处理草图:
import java.util.*;
java.util.List<String> list = Arrays.asList("a", "b", "c");
textFont(loadFont("UMingCN-30.vlw"));
for(int i = 0; i < list.size(); i++) {
text(list.get(i), 5, int(i*30)+30);
}
并且有一个非商业版本的 JEP (GPL) 可用。在此处下载并将其添加到您的处理类路径(导入它)。成功后,您可以像这样使用 JEP:
void setup() {
org.nfunk.jep.JEP parser = new org.nfunk.jep.JEP();
parser.addComplex();
try {
parser.parseExpression("(1+2*i) + (3+8*i)");
println(parser.getComplexValue());
} catch(Exception e) {
e.printStackTrace();
}
}
产生(预期的)输出: (4.0, 10.0)
看看这个: http ://bracer.sourceforge.net这是我实现的分流场算法,这个解析器支持复数。
如果由于某种原因您需要比迄今为止建议的“固定”复杂数学表达式解析器更大的灵活性(= 完全控制运算符、优先级、树结构),您可能需要考虑我的可配置解析器:
https://github.com/stefanhaustein/expressionparser
您的案例的直接评估代码示例:
static HashMap<String, Complex> variables = new HashMap<>();
/**
* Processes the calls from the parser directly to a Complex value.
*/
static class ComplexProcessor extends ExpressionParser.Processor<Complex> {
@Override
public Complex infixOperator(ExpressionParser.Tokenizer tokenizer, String name, Complex left, Complex right) {
switch (name.charAt(0)) {
case '+': return left.plus(right);
case '-': return left.minus(right);
case '*': return left.times(right);
case '/': return left.divides(right);
case '^':
if (right.im() != 0 || right.re() == (int) right.re()) {
return left.pow((int) right.re());
}
throw new RuntimeException("Only integer exponents supported by Complex.pow().");
default:
throw new IllegalArgumentException();
}
}
@Override
public Complex prefixOperator(ExpressionParser.Tokenizer tokenizer, String name, Complex argument) {
return name.equals("-") ? new Complex(0,0).minus(argument) : argument;
}
@Override
public Complex numberLiteral(ExpressionParser.Tokenizer tokenizer, String value) {
return new Complex(Double.parseDouble(value), 0);
}
@Override
public Complex identifier(ExpressionParser.Tokenizer tokenizer, String name) {
Complex value = variables.get(name);
if (value == null) {
throw new IllegalArgumentException("Undeclared variable: " + name);
}
return value;
}
@Override
public Complex group(ExpressionParser.Tokenizer tokenizer, String paren, List<Complex> elements) {
return elements.get(0);
}
/**
* Creates a parser for this processor with matching operations and precedences set up.
*/
static ExpressionParser<Complex> createParser() {
ExpressionParser<Complex> parser = new ExpressionParser<Complex>(new ComplexProcessor());
parser.addCallBrackets("(", ",", ")");
parser.addGroupBrackets("(", null, ")");
parser.addOperators(ExpressionParser.OperatorType.INFIX_RTL, 4, "^");
parser.addOperators(ExpressionParser.OperatorType.PREFIX, 3, "+", "-");
// 2 Reserved for implicit multiplication
parser.addOperators(ExpressionParser.OperatorType.INFIX, 1, "*", "/");
parser.addOperators(ExpressionParser.OperatorType.INFIX, 0, "+", "-");
return parser;
}
}
示例调用:
variables.put("i", new Complex(0, 1));
variables.put("z", new Complex(1, 1));
ExpressionParser<Complex> parser = ComplexProcessor.createParser();
System.out.println("(z^2)/(z/2):", parser.parse("(z^2)/(z/2)"));
解析器本身是在一个没有依赖关系的java 文件中实现的,因此出于评估目的,它很容易复制到您自己的项目中
我会(并且实际上)手动制作一个解析表并使用简单的 LR 或 LALR 解析器来处理它。在减少时,您可以执行计算。这样做的一个优点是很容易修改“语言”或可接受的输入。
这是一个直接的数学表达式解析器的链接(64 行):http: //javadots.blogspot.com/2008/11/arithemetic-expressions-solver-in-64.html
调整它以支持您的需求应该不会太困难
使用Apache Common Math。这是非常容易使用。
您可以初始化实部+虚部。您还可以从字符串初始化它们。它支持您可以使用虚数进行的各种操作。
以下是执行一些常见操作的代码示例:
package complex;
import static java.lang.String.format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.complex.ComplexFormat;
public class Do
{
public static void main(String[] args)
{
ComplexFormat format = new ComplexFormat();
Complex lhs = new Complex(1.0, 3.0);
Complex rhs = new Complex(2.0, 5.0);
Complex answer = lhs.add(rhs); // add two complex numbers
System.out.println("Add : "+ format.format(answer));
answer = lhs.subtract(rhs); // subtract two complex numbers
System.out.println("Subtract : "+ format.format(answer));
answer = lhs.conjugate();
System.out.println("Conjgate : "+ format.format(answer));
double d = lhs.abs();
System.out.println("Absolute : "+d);
Complex first = new Complex(1.0, 3.0);
Complex second = new Complex(2.0, 5.0);
answer = first.log(); // natural logarithm.
System.out.println("Logarithm : "+ format.format(answer));
answer = first.cos(); // cosine
System.out.println("Cosine : "+ format.format(answer));
answer = first.pow(second); // first raised to the power of second
System.out.println("Power : "+ format.format(answer));
Complex z = new Complex(2.0,2.0);
Complex z1 = z.reciprocal();
System.out.println("Recipocal : "+ format.format(z1));
System.out.println("Absoltue of 2+2i is "+z.abs());
System.out.println("Argument of 2+2i is "+z.getArgument());
Complex r = new Complex(6.3,9.6);
String conj = format.format(r.conjugate());
String reci = format.format(r.reciprocal());
System.out.println("Conjugate : "+conj+" Recipocal : "+reci);
//answer = lhs.abs(); // absolute value
//answer = lhs.conjugate(rhs); // complex conjugate
//make complex to string
ComplexFormat format = new ComplexFormat(); // default format
Complex c = new Complex(1.1111, 2.2222);
String s = format.format(c); // s contains "1.11 + 2.22i"
System.out.println(s);
//make string to complex
String z = "2.5+3.6i";
Complex e = format.parse(z);
System.out.println(e);
}
}
如果您想要另一种选择,另一种选择是FrAid 。