문제

나는 프로그램을 작성하고 있습니다 처리 복소수를 변환합니다. 그러나 입력 문자열을 취하고 복잡한 변수를 사용하여 변환을 계산하는 방법을 원합니다. 예를 들어:

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 그것은 분로 야드 알고리즘을 구현 하고이 파서는 복소수를 지원합니다.

어떤 이유로 든 지금까지 제안 된 "Canned"복잡한 수학 표현 파서보다 더 많은 유연성이 필요하다면 (= 연산자, 우선 순위, 트리 구성에 대한 완전한 제어) 내 구성 가능한 구문 분석기를 고려할 수 있습니다.

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

파서 자체는 단일로 구현됩니다 자바 파일 종속성이 없으면 평가 목적으로 자신의 프로젝트에 복사하는 것이 간단합니다.

나는 (그리고 실제로) 수동으로 구문 분석 테이블을 만들고 간단한 LR 또는 LALR 파서를 사용하여 처리 할 것입니다. 감소하면 계산을 수행 할 수 있습니다. 이에 대한 한 가지 장점은 "언어"또는 허용 가능한 입력을 쉽게 수정하는 것이 쉽다는 것입니다.

다음은 미친 솔루션입니다. Java에는 내장 JavaScript 엔진이 있습니다 (처리에서 액세스 할 수 있다고 가정합니다). 이제 복소 번호로 작동하는 JavaScript 클래스를 작성하십시오 (복사 여기). 그런 다음 지정된대로 수학 연산자를 과부하합니다 여기. 그 후에는 Java 에서이 문자열을 평가할 수 있습니다. 그것은 미쳤고 그것이 효과가 있을지 확신하지 못한다 (나는 JavaScript를 모른다). 어쩌면 구문 분석 표현없이 단순한 솔루션을 찾을 수있을 것입니다.

다음은 간단한 수학 표현 파서 (64 라인)에 대한 링크입니다. http://javadots.blogspot.com/2008/11/arithemetic-expressions-solver-in-64.html

귀하의 요구를 지원하기 위해 조정하는 것은 너무 어렵지 않아야합니다.

사용 아파치 일반 수학. 사용하기가 매우 쉽습니다.

실제+가상 부분을 모두 초기화 할 수 있습니다. 문자열에서 초기화 할 수도 있습니다. 상상의 숫자로 수행 할 수있는 광범위한 작업을 지원합니다.

다음은 몇 가지 일반적인 작업을 수행하기위한 코드의 예입니다.

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, 다른 옵션을 원한다면.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top