如何解决简单的String算术表达式,例如5-2 * 10?

时间:2014-10-07 20:25:40

标签: java integer-arithmetic

由于某种原因,我在尝试这样做时遇到了很多麻烦。我有一个类要求我使用递归来评估复杂的Java表达式,例如(3 + 5 [3 * 2-4])。我想我对如何处理它有一个想法,但我似乎无法弄清楚如何首先解决一些非常简单的问题 - 比如

5-2 * 10

我不知道该怎么做。它们不允许您导入任何外部脚本,也不允许将其转换为后缀表达式。

我不指望有人给我写代码,但是如果有人可以把我送到正确的方向或给我一点伪代码我真的很感激 - 我花了两个小时无济于事了解我如何使用字符串标记符和其他东西来解决它,但我总是遇到一堵墙,我不知道如何绕过它。非常感谢提前!

4 个答案:

答案 0 :(得分:0)

你可以连续减少子表达式(所谓的“redexes”),直到不再可能减少为止。

可以使用正则表达式替换内部表达式:

  1. “(\ d +)([* /])( - ?\ d +)”
  2. “(\ d +)([+ - ])( - ?\ d +)”
  3. “\ [( - ?\ d +)\]”
  4. ...
  5. 循环循环。参见Pattern,Matcher,find。

    由于这似乎是作业,我向你提出了进一步的挑战。

    负数可能有点挑战,可能会尝试一元减号运算符。

答案 1 :(得分:0)

回到大学,我也必须这样做。

我采取的方法是parse expressions using recursive descent。本文非常好地概述了解析器应如何对输入进行标记,然后您可以继续进行评估。你必须要在这里实现的关键是,如果你要在解析树的底部开始使用单个字符然后使用规则来连接,那么使你的解析器成为top-down会让你的生活变得更加容易。将字符组合成更大的标记,因为我们要求您维护堆栈并使其变得过于复杂。与此相关,因为您知道您所做的一切都是逻辑运算,您可以首先假设您的表达式符合您的生产规则,然后您可以继续查看此假设的内部逻辑含义。

如果您选择构建自上而下的解析器或自下而上的解析器,这些Brief Notes on Parsing实际上很好地解释了实现的差异。但是,根据解析器需要处理的表达式的复杂程度,您可能choose to implement a bottom-up parser,因为尽管它们的复杂性,但是自下而上的解析算法比自上而下更强大。

我构建的解析器是在OCaml中,函数式编程对于这个用例来说是一个非常好的解决方案。

如果您有任何疑问,请与我们联系!

答案 2 :(得分:0)

要求您实施表达式分析器。

以下是通常如何完成的摘要。您可以交替使用以下步骤从左向右扫描字符串。每种方法都会消耗一些文本并返回一个整数值。

  • 评估整数的方法:以数字开头。收集所有连续的数字并将其转换为值。
  • 评估因子的方法:如果以数字开头,则计算整数。如果以'('开头,则评估表达式。如果不是,则表示错误。
  • 评估术语的方法:评估因素。当下一个字符是*或a /时,跳过它,评估一个额外的因子,并将前一个值乘以或除以新值。
  • 评估总和的方法:评估术语。当下一个字符是+或a - 时,跳过它,评估一个额外的术语,并将新值加上或减去前一个值。
  • 评估表达式的方法:它以'('。跳过并评估总和。如果下一个字符是')',则跳过它。如果没有,那就是错误。

答案 3 :(得分:0)

对于简单的字符串操作,例如" 5-2 * 10",一个解决方案是:

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

我不想考虑不导入的想法。

基本上,这是"计算"的代码。假设表达式5-2 * 10是在TextField中引入的:

ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        String r = jTextField1.getText();
        try {
            jTextField1.setText(engine.eval(r).toString());

        } catch (ScriptException ex) {
            Logger.getLogger(MegaCal.class.getName()).log(Level.SEVERE, null, ex);
        }