Frage

Ich schreibe ein Programm in Verarbeitung , die komplexen Zahlen umwandelt. Allerdings möchte ich eine Eingabezeichenfolge des Nehmens ein Verfahren haben und die Transformation unter Verwendung einer komplexen Variablen zu berechnen. Zum Beispiel:

1/(z+1)
(z^2)/(z/2)

, wobei z eine komplexe Zahl. Jetzt habe ich bei GEP sah und einige Beispiele , aber ich kann nicht arbeiten, wenn es Ihnen erlauben würde, tatsächlich z als Variable eingeben (und in jedem Fall ist es nicht kostenlos). Gibt es einen Ausdruck Parser für Java (die in der Verarbeitung arbeitet, die eine alte Version von Java verwendet und keine Generika), dass ich dies zu tun verwenden könnte?

Wenn nicht, könnte mir jemand zeigen auf die Grundlagen, wie man erstellen?

War es hilfreich?

Lösung

Wie Philo erwähnt, können Sie Generika verwenden. Versuchen Sie, diese Verarbeitung Skizze:

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);
}

Und es gibt eine nicht kommerzielle Version von JEP verfügbar (GPL). Laden Sie es

Andere Tipps

Haben Sie einen Blick auf diese: http://bracer.sourceforge.net Es ist meine Implementierung ist der Rangieren-Yard Algorithmus und diese Parser unterstützt komplexe Zahlen.

Wenn aus irgendeinem Grund müssen Sie mehr Flexibilität als die „Konserven“ komplexen mathematischen Ausdruck Parser bisher vorgeschlagen (= volle Kontrolle über Operatoren Vorrang, Baumkonstruktion), Sie können meine konfigurierbare Parser zu berücksichtigen:

https://github.com/stefanhaustein/expressionparser

Beispiel direkte Auswertung Code für Ihren Fall:

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;
  }
}

Beispiel Aufruf:

  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)"));

Der Parser selbst in einem einzigen Java-Datei ohne Abhängigkeiten, so für die Auswertung ist es einfach auf Ihr eigenes Projekt kopieren

Ich würde (und haben, tatsächlich) manuell eine Parsing-Tabelle machen und eine einfache LR oder LALR Parser zu verarbeiten verwenden. Bei einer Reduktion können Sie die Berechnungen durchführen. Ein Vorteil ist, dass es einfach ist, die „Sprache“ oder akzeptablen Eingabe zu ändern.

Hier ist verrückt Lösung: Java hat integrierte JavaScript-Engine (ich nehme Sie es von der Verarbeitung zugreifen kann). Jetzt können Sie eine JavaScript-Klasse schreiben, die mit komplexen Zahlen arbeiten (kopieren von hier ). Dann überlastete mathematische Operatoren wie angegeben hier . Danach können Sie eval nur diese Zeichenfolge aus Java. Es ist verrückt, und ich bin nicht sicher, dass es funktioniert (ich weiß Javascript nicht). Vielleicht wird es machen, ohne Parsen Ausdrücke etwas einfachere Lösung zu finden.

Hier ist ein Link zu einem Straight-Forward-mathematischen Ausdruck Parser (64 Zeilen): http://javadots.blogspot.com/2008/11/arithemetic-expressions-solver-in-64.html

es Tweaking Ihre Bedürfnisse unterstützen sollte nicht allzu schwierig sein

Verwenden Sie Apache Commons Math . Es ist sehr einfach zu bedienen.

können Sie initialisieren sowohl real + imaginäre Teile. Sie können sie auch aus einem String initialisieren. Es unterstützt eine breite Palette von Operationen, die Sie mit imaginären Zahlen tun können.

Hier ist ein Beispiel-Code für einige gemeinsame Operationen auf:

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);

}    
}

Eine weitere Alternative ist Fraid , wenn Sie eine andere Option wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top