문자열 형식으로 주어진 수학 식을 어떻게 평가합니까?
의 식을 을 쓰려고 String
다음 중 하나:
"5+3"
"10-40"
"(1+10)*3"
if-then-else 문장은 많이 피하고 싶어요.이거 어떻게 해?
JDK1.6에서는 내장된 Javascript 엔진을 사용할 수 있습니다.
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
public class Test {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
글을 eval
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★♪ 곱셈, 나눗셈, , 뺄셈, 뺄셈, 나눗셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈, 뺄셈을 사용합니다.^
와 같은 몇 을 사용합니다.sqrt
을 사용해서 그룹화를 할 수 .(
)
오퍼레이터 우선순위 및 어소시에이티비티 규칙을 올바르게 취득합니다.
public static double eval(final String str) {
return new Object() {
int pos = -1, ch;
void nextChar() {
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
}
boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
double parse() {
nextChar();
double x = parseExpression();
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
return x;
}
// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor
// factor = `+` factor | `-` factor | `(` expression `)` | number
// | functionName `(` expression `)` | functionName factor
// | factor `^` factor
double parseExpression() {
double x = parseTerm();
for (;;) {
if (eat('+')) x += parseTerm(); // addition
else if (eat('-')) x -= parseTerm(); // subtraction
else return x;
}
}
double parseTerm() {
double x = parseFactor();
for (;;) {
if (eat('*')) x *= parseFactor(); // multiplication
else if (eat('/')) x /= parseFactor(); // division
else return x;
}
}
double parseFactor() {
if (eat('+')) return +parseFactor(); // unary plus
if (eat('-')) return -parseFactor(); // unary minus
double x;
int startPos = this.pos;
if (eat('(')) { // parentheses
x = parseExpression();
if (!eat(')')) throw new RuntimeException("Missing ')'");
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(str.substring(startPos, this.pos));
} else if (ch >= 'a' && ch <= 'z') { // functions
while (ch >= 'a' && ch <= 'z') nextChar();
String func = str.substring(startPos, this.pos);
if (eat('(')) {
x = parseExpression();
if (!eat(')')) throw new RuntimeException("Missing ')' after argument to " + func);
} else {
x = parseFactor();
}
if (func.equals("sqrt")) x = Math.sqrt(x);
else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
else throw new RuntimeException("Unknown function: " + func);
} else {
throw new RuntimeException("Unexpected: " + (char)ch);
}
if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation
return x;
}
}.parse();
}
예제:
System.out.println(eval("((4 - 2^3 + 1) * -sqrt(3*3+4*4)) / 2"));
출력: 7.5 (정답)
파서는 재귀적 하강 파서이므로 내부적으로 문법의 연산자 우선 순위 수준별로 별도의 해석 방법을 사용합니다.일부러 짧게 설명했지만, 다음은 확장해야 할 몇 가지 아이디어입니다.
변수:
위해 할 수 .커스텀 변수 수 .
eval
「」와 메서드는,Map<String,Double> variables
.별도의 컴파일 및 평가:
변수에 대한 지원을 추가한 후 매번 구문 분석하지 않고 변경된 변수를 사용하여 동일한 식을 수백만 번 평가하려면 어떻게 해야 합니까?가능합니다.먼저 사전 컴파일된 식을 평가하기 위해 사용할 인터페이스를 정의합니다.
@FunctionalInterface interface Expression { double eval(); }
" 를 "하려면 "eval" "parse"를 반환하는 합니다.
double
그 대신 그 인터페이스의 인스턴스를 반환합니다.자바8「 」 「 」 、 「 。Expression parseExpression() { Expression x = parseTerm(); for (;;) { if (eat('+')) { // addition Expression a = x, b = parseTerm(); x = (() -> a.eval() + b.eval()); } else if (eat('-')) { // subtraction Expression a = x, b = parseTerm(); x = (() -> a.eval() - b.eval()); } else { return x; } } }
트리가 .
Expression
컴파일된 표현식을 나타내는 오브젝트(추상 구문 트리).그런 다음 한 번 컴파일하고 다른 값으로 반복적으로 평가할 수 있습니다.public static void main(String[] args) { Map<String,Double> variables = new HashMap<>(); Expression exp = parse("x^2 - x + 2", variables); for (double x = -20; x <= +20; x++) { variables.put("x", x); System.out.println(x + " => " + exp.eval()); } }
다른 데이터 유형:
double
한 것을 할 수BigDecimal
또는 복소수 또는 유리수(예: 유리수)를 구현하는 클래스입니다.사용할 수도 있습니다.Object
이 응답의 모든 코드가 공용 도메인에 릴리스되었습니다.재미있게 보내!
대학 프로젝트에서는 기본 공식과 더 복잡한 방정식(특히 반복 연산자)을 모두 지원하는 파서/평가자를 찾고 있었습니다.JAVA 및 JAVA용 오픈소스 라이브러리는 매우 훌륭했습니다.MXparser라는 이름의 NET.구문에 대한 느낌을 살리기 위해 몇 가지 예를 들겠습니다. 자세한 설명은 프로젝트 웹사이트(특히 튜토리얼 섹션)를 참조하십시오.
https://mathparser.org/mxparser-tutorial/
몇 가지 예를 들어
1 - 심플 퍼뮬라
Expression e = new Expression("( 2 + 3/4 + sin(pi) )/2");
double v = e.calculate()
2 - 사용자 정의 인수 및 상수
Argument x = new Argument("x = 10");
Constant a = new Constant("a = pi^2");
Expression e = new Expression("cos(a*x)", x, a);
double v = e.calculate()
3 - 사용자 정의 함수
Function f = new Function("f(x, y, z) = sin(x) + cos(y*z)");
Expression e = new Expression("f(3,2,5)", f);
double v = e.calculate()
4 - 반복
Expression e = new Expression("sum( i, 1, 100, sin(i) )");
double v = e.calculate()
최근에 발견 - 구문을 사용해 보고 싶은 경우(및 고급 사용 사례 참조) mXparser를 탑재한 Scalar Calculator 앱을 다운로드할 수 있습니다.
이 문제를 해결하는 올바른 방법은 렉서 및 파서를 사용하는 것입니다.이러한 페이지의 간단한 버전을 직접 작성할 수도 있고, Java 렉서 및 파서에 대한 링크도 있습니다.
재귀 하강 파서를 만드는 것은 정말 좋은 학습 연습입니다.
여기에는 EvalEx라는 이름의 GitHub의 또 다른 오픈 소스 라이브러리는 GitHub에 있습니다.
JavaScript 엔진과 달리 이 라이브러리는 수학식만 평가하는 데 중점을 두고 있습니다.또한 라이브러리는 확장 가능하며 괄호뿐만 아니라 부울 연산자의 사용을 지원합니다.
Java 응용 프로그램이 이미 데이터베이스에 액세스한 경우 다른 JAR을 사용하지 않고 식을 쉽게 평가할 수 있습니다.
일부 데이터베이스에서는 더미 테이블(예를 들어 Oracle의 "듀얼" 테이블)을 사용해야 하며, 다른 데이터베이스에서는 테이블에서 "선택"하지 않고 식을 평가할 수 있습니다.
예를 들어 SQL 서버 또는 SQLite에서
select (((12.10 +12.0))/ 233.0) amount
및 Oracle에서
select (((12.10 +12.0))/ 233.0) amount from dual;
DB를 사용하면 여러 식을 동시에 평가할 수 있다는 장점이 있습니다.또한 대부분의 DB에서는 매우 복잡한 식을 사용할 수 있으며 필요에 따라 호출할 수 있는 여러 추가 함수도 있습니다.
그러나 많은 단일 식을 개별적으로 평가해야 하는 경우, 특히 DB가 네트워크 서버에 있는 경우 성능이 저하될 수 있습니다.
다음은 Sqlite 인메모리 데이터베이스를 사용하여 성능 문제를 어느 정도 해결합니다.
다음은 Java의 전체 작업 예제입니다.
Class. forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount");
rs.next();
System.out.println(rs.getBigDecimal(1));
stat.close();
conn.close();
물론 위의 코드를 확장하여 동시에 여러 계산을 처리할 수 있습니다.
ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount, (1+100)/20.0 amount2");
BeanShell 인터프리터를 사용해 볼 수도 있습니다.
Interpreter interpreter = new Interpreter();
interpreter.eval("result = (7+21*6)/(32-27)");
System.out.println(interpreter.get("result"));
또 다른 방법은 스프링식 언어(Spring Expression Language)를 사용하는 것입니다.스펠은 수학식 평가와 함께 훨씬 더 많은 것을 하기 때문에 약간 과잉일 수 있습니다.이 표현식 라이브러리는 독립 실행형이므로 Spring 프레임워크를 사용할 필요가 없습니다.SPEL 문서에서 예제를 복사하는 방법:
ExpressionParser parser = new SpelExpressionParser();
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); //24.0
이 기사에서는 다양한 접근법에 대해 설명합니다.이 기사에서 언급한 2가지 주요 접근방식은 다음과 같습니다.
Apache의 JEXL
Java 개체에 대한 참조를 포함하는 스크립트를 허용합니다.
// Create or retrieve a JexlEngine
JexlEngine jexl = new JexlEngine();
// Create an expression object
String jexlExp = "foo.innerFoo.bar()";
Expression e = jexl.createExpression( jexlExp );
// Create a context and add data
JexlContext jctx = new MapContext();
jctx.set("foo", new Foo() );
// Now evaluate the expression, getting the result
Object o = e.evaluate(jctx);
JDK에 내장된 Javascript 엔진을 사용합니다.
private static void jsEvalWithVariable()
{
List<String> namesList = new ArrayList<String>();
namesList.add("Jill");
namesList.add("Bob");
namesList.add("Laureen");
namesList.add("Ed");
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.put("namesListKey", namesList);
System.out.println("Executing in script environment...");
try
{
jsEngine.eval("var x;" +
"var names = namesListKey.toArray();" +
"for(x in names) {" +
" println(names[x]);" +
"}" +
"namesListKey.add(\"Dana\");");
}
catch (ScriptException ex)
{
ex.printStackTrace();
}
}
구현하려면 다음 알고리즘을 사용할 수 있습니다.--
아직 읽을 토큰이 있는 동안
1.1 다음 토큰을 가져옵니다. 1.2 토큰이 다음과 같은 경우:
1.2.1 A 숫자: 값 스택에 푸시합니다.
1.2.2 변수: 값을 얻고 값 스택에 푸시합니다.
1.2.3 왼쪽 괄호: 오퍼레이터 스택에 밀어 넣습니다.
1.2.4 오른쪽 괄호:
1 While the thing on top of the operator stack is not a left parenthesis, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack. 2 Pop the left parenthesis from the operator stack, and discard it.
1.2.5 오퍼레이터(thisOp이라고 부릅니다):
1 While the operator stack is not empty, and the top thing on the operator stack has the same or greater precedence as thisOp, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack. 2 Push thisOp onto the operator stack.
연산자 스택이 비어 있지 않은 동안 1 연산자 스택에서 연산자를 팝합니다. 2 값 스택을 두 번 팝하면 두 개의 오퍼랜드를 얻을 수 있습니다.3 연산자를 올바른 순서로 오퍼랜드에 적용하고 4 결과를 값 스택에 푸시한다.
이 시점에서 연산자 스택은 비어 있어야 하며 값 스택에는 값이 1개만 있어야 합니다.이것은 최종 결과입니다.
이것은 또 다른 흥미로운 대안입니다.https://github.com/Shy-Ta/expression-evaluator-demo
사용법은 매우 간단하며, 다음과 같이 작업을 완료합니다.
ExpressionsEvaluator evalExpr = ExpressionsFactory.create("2+3*4-6/2");
assertEquals(BigDecimal.valueOf(11), evalExpr.eval());
JEP가 그 일을 해야 할 것 같다.
대답하기엔 너무 늦었지만 자바 표현법을 평가하기 위해 같은 상황을 만났는데, 누군가 도움이 될 수 있습니다.
MVEL
평가를 하려면 , 「자바 코드」를 사용합니다. 을 사용하다String
이치노
String expressionStr = "x+y";
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("x", 10);
vars.put("y", 20);
ExecutableStatement statement = (ExecutableStatement) MVEL.compileExpression(expressionStr);
Object result = MVEL.executeExpression(statement, vars);
어떤 식으로 하든 많은 조건들이 수반될 것입니다.그러나 예시와 같은 단일 작업의 경우 다음과 같은 문장이 포함된 경우 4로 제한할 수 있습니다.
String math = "1+4";
if (math.split("+").length == 2) {
//do calculation
} else if (math.split("-").length == 2) {
//do calculation
} ...
"4+5*6"과 같은 여러 작업을 처리하려는 경우 훨씬 더 복잡해집니다.
계산기를 작성하려는 경우 계산의 각 섹션을 하나의 문자열이 아닌 별도로(각 숫자 또는 연산자) 전달하는 것이 좋습니다.
Symja 프레임워크는 다음과 같습니다.
ExprEvaluator util = new ExprEvaluator();
IExpr result = util.evaluate("10-40");
System.out.println(result.toString()); // -> "-30"
보다 복잡한 표현은 확실히 평가할 수 있습니다.
// D(...) gives the derivative of the function Sin(x)*Cos(x)
IAST function = D(Times(Sin(x), Cos(x)), x);
IExpr result = util.evaluate(function);
// print: Cos(x)^2-Sin(x)^2
코드 주입 핸들링과 함께 JDK1.6의 Javascript 엔진을 사용하여 다음 샘플 코드를 사용해 보십시오.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class EvalUtil {
private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
public static void main(String[] args) {
try {
System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || 5 >3 "));
System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || true"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Object eval(String input) throws Exception{
try {
if(input.matches(".*[a-zA-Z;~`#$_{}\\[\\]:\\\\;\"',\\.\\?]+.*")) {
throw new Exception("Invalid expression : " + input );
}
return engine.eval(input);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
이는 사실상 @Boann의 답변을 보완하는 것이다."-2 ^2"가 -4.0의 잘못된 결과를 나타내는 약간의 버그가 있습니다.그것에 대한 문제는 그의 지수를 평가하는 지점이다.parseTerm() 블록으로 지수를 이동하기만 하면 됩니다.@Boann의 답변을 약간 수정한 아래를 보세요.수정은 댓글에 있습니다.
public static double eval(final String str) {
return new Object() {
int pos = -1, ch;
void nextChar() {
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
}
boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
double parse() {
nextChar();
double x = parseExpression();
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
return x;
}
// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor
// factor = `+` factor | `-` factor | `(` expression `)`
// | number | functionName factor | factor `^` factor
double parseExpression() {
double x = parseTerm();
for (;;) {
if (eat('+')) x += parseTerm(); // addition
else if (eat('-')) x -= parseTerm(); // subtraction
else return x;
}
}
double parseTerm() {
double x = parseFactor();
for (;;) {
if (eat('*')) x *= parseFactor(); // multiplication
else if (eat('/')) x /= parseFactor(); // division
else if (eat('^')) x = Math.pow(x, parseFactor()); //exponentiation -> Moved in to here. So the problem is fixed
else return x;
}
}
double parseFactor() {
if (eat('+')) return parseFactor(); // unary plus
if (eat('-')) return -parseFactor(); // unary minus
double x;
int startPos = this.pos;
if (eat('(')) { // parentheses
x = parseExpression();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(str.substring(startPos, this.pos));
} else if (ch >= 'a' && ch <= 'z') { // functions
while (ch >= 'a' && ch <= 'z') nextChar();
String func = str.substring(startPos, this.pos);
x = parseFactor();
if (func.equals("sqrt")) x = Math.sqrt(x);
else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
else throw new RuntimeException("Unknown function: " + func);
} else {
throw new RuntimeException("Unexpected: " + (char)ch);
}
//if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation -> This is causing a bit of problem
return x;
}
}.parse();
}
package ExpressionCalculator.expressioncalculator;
import java.text.DecimalFormat;
import java.util.Scanner;
public class ExpressionCalculator {
private static String addSpaces(String exp){
//Add space padding to operands.
//https://regex101.com/r/sJ9gM7/73
exp = exp.replaceAll("(?<=[0-9()])[\\/]", " / ");
exp = exp.replaceAll("(?<=[0-9()])[\\^]", " ^ ");
exp = exp.replaceAll("(?<=[0-9()])[\\*]", " * ");
exp = exp.replaceAll("(?<=[0-9()])[+]", " + ");
exp = exp.replaceAll("(?<=[0-9()])[-]", " - ");
//Keep replacing double spaces with single spaces until your string is properly formatted
/*while(exp.indexOf(" ") != -1){
exp = exp.replace(" ", " ");
}*/
exp = exp.replaceAll(" {2,}", " ");
return exp;
}
public static Double evaluate(String expr){
DecimalFormat df = new DecimalFormat("#.####");
//Format the expression properly before performing operations
String expression = addSpaces(expr);
try {
//We will evaluate using rule BDMAS, i.e. brackets, division, power, multiplication, addition and
//subtraction will be processed in following order
int indexClose = expression.indexOf(")");
int indexOpen = -1;
if (indexClose != -1) {
String substring = expression.substring(0, indexClose);
indexOpen = substring.lastIndexOf("(");
substring = substring.substring(indexOpen + 1).trim();
if(indexOpen != -1 && indexClose != -1) {
Double result = evaluate(substring);
expression = expression.substring(0, indexOpen).trim() + " " + result + " " + expression.substring(indexClose + 1).trim();
return evaluate(expression.trim());
}
}
String operation = "";
if(expression.indexOf(" / ") != -1){
operation = "/";
}else if(expression.indexOf(" ^ ") != -1){
operation = "^";
} else if(expression.indexOf(" * ") != -1){
operation = "*";
} else if(expression.indexOf(" + ") != -1){
operation = "+";
} else if(expression.indexOf(" - ") != -1){ //Avoid negative numbers
operation = "-";
} else{
return Double.parseDouble(expression);
}
int index = expression.indexOf(operation);
if(index != -1){
indexOpen = expression.lastIndexOf(" ", index - 2);
indexOpen = (indexOpen == -1)?0:indexOpen;
indexClose = expression.indexOf(" ", index + 2);
indexClose = (indexClose == -1)?expression.length():indexClose;
if(indexOpen != -1 && indexClose != -1) {
Double lhs = Double.parseDouble(expression.substring(indexOpen, index));
Double rhs = Double.parseDouble(expression.substring(index + 2, indexClose));
Double result = null;
switch (operation){
case "/":
//Prevent divide by 0 exception.
if(rhs == 0){
return null;
}
result = lhs / rhs;
break;
case "^":
result = Math.pow(lhs, rhs);
break;
case "*":
result = lhs * rhs;
break;
case "-":
result = lhs - rhs;
break;
case "+":
result = lhs + rhs;
break;
default:
break;
}
if(indexClose == expression.length()){
expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose);
}else{
expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose + 1);
}
return Double.valueOf(df.format(evaluate(expression.trim())));
}
}
}catch(Exception exp){
exp.printStackTrace();
}
return 0.0;
}
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.print("Enter an Mathematical Expression to Evaluate: ");
String input = scanner.nextLine();
System.out.println(evaluate(input));
}
}
import java.util.*;
public class check {
int ans;
String str="7 + 5";
StringTokenizer st=new StringTokenizer(str);
int v1=Integer.parseInt(st.nextToken());
String op=st.nextToken();
int v2=Integer.parseInt(st.nextToken());
if(op.equals("+")) { ans= v1 + v2; }
if(op.equals("-")) { ans= v1 - v2; }
//.........
}
수식을 평가할 수 있는 Java 클래스:
package test;
public class Calculator {
public static Double calculate(String expression){
if (expression == null || expression.length() == 0) {
return null;
}
return calc(expression.replace(" ", ""));
}
public static Double calc(String expression) {
if (expression.startsWith("(") && expression.endsWith(")")) {
return calc(expression.substring(1, expression.length() - 1));
}
String[] containerArr = new String[]{expression};
double leftVal = getNextOperand(containerArr);
expression = containerArr[0];
if (expression.length() == 0) {
return leftVal;
}
char operator = expression.charAt(0);
expression = expression.substring(1);
while (operator == '*' || operator == '/') {
containerArr[0] = expression;
double rightVal = getNextOperand(containerArr);
expression = containerArr[0];
if (operator == '*') {
leftVal = leftVal * rightVal;
} else {
leftVal = leftVal / rightVal;
}
if (expression.length() > 0) {
operator = expression.charAt(0);
expression = expression.substring(1);
} else {
return leftVal;
}
}
if (operator == '+') {
return leftVal + calc(expression);
} else {
return leftVal - calc(expression);
}
}
private static double getNextOperand(String[] exp){
double res;
if (exp[0].startsWith("(")) {
int open = 1;
int i = 1;
while (open != 0) {
if (exp[0].charAt(i) == '(') {
open++;
} else if (exp[0].charAt(i) == ')') {
open--;
}
i++;
}
res = calc(exp[0].substring(1, i - 1));
exp[0] = exp[0].substring(i);
} else {
int i = 1;
if (exp[0].charAt(0) == '-') {
i++;
}
while (exp[0].length() > i && isNumber((int) exp[0].charAt(i))) {
i++;
}
res = Double.parseDouble(exp[0].substring(0, i));
exp[0] = exp[0].substring(i);
}
return res;
}
private static boolean isNumber(int c) {
int zero = (int) '0';
int nine = (int) '9';
return (c >= zero && c <= nine) || c =='.';
}
public static void main(String[] args) {
System.out.println(calculate("(((( -6 )))) * 9 * -1"));
System.out.println(calc("(-5.2+-5*-5*((5/4+2)))"));
}
}
이런 건 어때?
String st = "10+3";
int result;
for(int i=0;i<st.length();i++)
{
if(st.charAt(i)=='+')
{
result=Integer.parseInt(st.substring(0, i))+Integer.parseInt(st.substring(i+1, st.length()));
System.out.print(result);
}
}
그리고 그에 따라 다른 모든 수학 연산자에 대해서도 비슷한 일을 한다.
Djikstra의 션팅 야드 알고리즘을 사용하여 infix 표기의 식 문자열을 postfix 표기로 변환할 수 있습니다.알고리즘의 결과는 식 결과를 반환하는 포스트픽스알고리즘에 대한 입력으로 기능할 수 있습니다.
또 다른 옵션: https://github.com/stefanhaustein/expressionparser
심플하지만 유연한 옵션을 제공하여 다음 두 가지를 모두 가능하게 하기 위해 이를 구현했습니다.
- 즉시처리(Calculator.java, SetDemo.java)
- 해석 트리 구축 및 처리(TreeBuilder.java)
위에 링크된 TreeBuilder는 심볼 파생 기능을 수행하는 CAS 데모 패키지의 일부입니다.BASIC 인터프리터의 예도 있고, 그것을 이용한 TypeScript 인터프리터 구축을 시작했습니다.
javascript를 실행하기 위해 RHINO나 NASHORN과 같은 외부 라이브러리를 사용할 수 있습니다.또한 Javascript는 문자열을 파싱하지 않고도 간단한 수식을 평가할 수 있습니다.코드가 올바르게 쓰여져 있으면 퍼포먼스에 영향을 주지 않습니다.다음은 RHINO의 예입니다.
public class RhinoApp {
private String simpleAdd = "(12+13+2-2)*2+(12+13+2-2)*2";
public void runJavaScript() {
Context jsCx = Context.enter();
Context.getCurrentContext().setOptimizationLevel(-1);
ScriptableObject scope = jsCx.initStandardObjects();
Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
Context.exit();
System.out.println(result);
}
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class test2 {
public static void main(String[] args) throws ScriptException {
String s = "10+2";
ScriptEngineManager mn = new ScriptEngineManager();
ScriptEngine en = mn.getEngineByName("js");
Object result = en.eval(s);
System.out.println(result);
}
}
언급URL : https://stackoverflow.com/questions/3422673/how-to-evaluate-a-math-expression-given-in-string-form
'sourcecode' 카테고리의 다른 글
Java: 0 <= x < n 범위의 난수 (0) | 2022.08.31 |
---|---|
계산된 구성 요소와 vuejs 동적 가져오기의 구성 요소를 가져올 때의 차이점은 무엇입니까? (0) | 2022.08.31 |
JDK와 JRE의 차이점은 무엇입니까? (0) | 2022.08.31 |
vue-router의 "$router.push()"에 사용자 지정 데이터 전달 (0) | 2022.08.31 |
@RequestParam 목록 바인딩 (0) | 2022.08.31 |