0

我正在尝试制作一个可以计算输入总和的计算器。

例子:

我尝试过这样的事情......

import java.util.*;

public class Calc {

String sum; 


     public static void main(String[]args){

            Scanner sum = new Scanner(System.in);

            System.out.println("Please enter a sum: ");

            double newsum = Integer.parseInt(sum);  

            sum.close();               

            System.out.println(newsum);

     }

}
4

6 回答 6

3

将所有内容都转换为字符串表达式后,您可以使用内置的 javascript 引擎来评估表达式。

import java.util.Scanner;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Example {
    public static void main(String[] args) throws Exception {
        System.out.println("Please enter an expression: ");
        String toEval = new Scanner(System.in).next();
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
        System.out.println(jsEngine.eval(toEval));
    }
}
于 2012-12-24T15:00:59.753 回答
1

您可以为此使用 ANTLR。您可以在此处找到示例计算器。

编辑

如果您使用 ANTLR,您将来可以很容易地添加更多功能,例如括号的使用、一些计算方法(例如 round、sin、cos)。

于 2012-12-24T14:59:06.827 回答
0

我不知道你在使用 java 方面有多先进,但如果你是为了好玩、学习和调查以获得最佳解决方案,也许值得考虑一种设计模式:即这种设计模式:http: //sourcemaking.com/ design_patterns/interpreter 至少是为了好玩

于 2012-12-24T15:06:53.047 回答
0

请看看这篇有不同表达评估技巧的好文章。它还包含对Jexel的引用,这在数学表达式中已经足够好了,下面是一个简短的示例:

JexlEngine jexl = new JexlEngine();
Expression func = jexl.createExpression("x1*x2-x3");
MapContext mc = new MapContext();
mc.set("x1", 5);
mc.set("x2", 3);
mc.set("x3", 2);
System.out.println(func.evaluate(mc));
于 2012-12-24T15:10:17.473 回答
0

这不适用于括号,我还没有测试过,但是这样的解决方案可能有效

for(int i = 0; i < equation.length; i++) {
    char c = equation.charAt(i);
    if(c == '*' || c == '/') {        // Operators with highest precedence
        double op1 = getNumBeforeIndex(i);
        double op2 = getNumAfterIndex(i, equation);
        double answer;

        switch(c) {                  // Perform sum
        case '*':
            answer = op1 * op2;
            break;
        case '/':
            answer = op1 / op2;
            break;
        }
    equation = replaceSumWithAnswer(i, equation, answer);
    }        
}

然后对 + 和 - 执行相同的操作。

对于 'getNumBeforeIndex' 和 'getNumAfterIndex',您需要从给定的索引循环,直到找到一个非数字字符。您还必须记住允许小数点和负数。

'replaceSumWithAnswer' 方法必须获取第一个操作数开头的索引,然后是第二个操作数的最后一个索引,然后用答案替换子字符串。

希望这可以为您指明正确的方向。

于 2012-12-24T15:13:16.367 回答
0

嗯,这是一个简单的问题,但答案有点复杂。如果不对表达式的语法做任何假设,您就无法像这样解析表达式。是中缀/后缀/前缀。它使用括号吗?加法是可交换的吗?乘法是左结合还是右结合?* 和 + 符号的实际含义是什么?

在构建计算器时需要做出许多决定,因此 Java 编程语言没有任何开箱即用的评估支持。如果您希望进行具有标准含义的操作,请使用一些库。如果您希望有一些非标准行为,请编写自己的语法。如果您将使用括号,则需要拉-推自动机来实现它,可能与LL1 语法结合使用。

但是,当你问这种问题时,我想你是 Java 和编程的新手。我不建议您尝试它,您需要一些自动机和语法理论的基础知识。

我在自学Java时也遇到了这个问题,我通过输入程序作为windows计算器解决了这个问题。该程序包含一个汇总当前结果的寄存器,并且在每次操作后程序都会向用户查询下一个结果(您也可以使用非常简单的解析器来做到这一点 - 但请记住,计算器不会识别运算符的优先级)。

于 2012-12-24T16:10:26.037 回答