Si pour une raison quelconque, vous avez besoin de plus de flexibilité que l'expression mathématique complexe « en boîte » parseurs proposées jusqu'à présent (= contrôle total sur les opérateurs, la priorité, la construction d'arbres), vous voudrez peut-être considérer mon analyseur configurable:
https://github.com/stefanhaustein/expressionparser
Exemple code d'évaluation directe pour votre cas:
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;
}
}
Exemple invocation:
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)"));
L'analyseur lui-même est mis en œuvre en une seule java file sans dépendances, donc à des fins d'évaluation, il est facile de copier sur votre propre projet
Pour votre information, le traitement n'utilise pas « une ancienne version de Java », il fonctionne très bien avec Java 1.6. Il peut utiliser des bibliothèques Java 1.6, et si vous avez besoin de génériques dans une esquisse, vous pouvez mettre cette partie dans un fichier .java. – PhiLho
Comment? Ce serait tellement utile! J'ai essayé beaucoup de déclaration d'importation mais aucun d'entre eux m'a permis de le faire. J'utilise l'IDE de traitement avec le dernier JDK de Sun. –