计算器问题

时间:2009-10-08 22:28:21

标签: java parsing

我想设计一个特殊的计算器.. 我遇到了这样的问题: X = 1 +(12 * 4 + 2) 我需要先获得一些操作数 像这里我有两个操作数1和(12 * 4 + 2) 我怎么能区分外部+和内部?

谢谢

这里有一个多么棒的社区.. 从最简单到最难的不同答案.. guyz我的问题不是计算器,也不是与数学相关的任何其他东西..  我刚才询问了外部和内部加分,以完全不同的方式应用策略。

我在java中实现统一算法(就像Prolog解释器在给出两个表达式时所做的那样)

这是算法:

function unify(E1, E2);
    begin
        case
            both E1 and E2 are constants or the empty list:
                if E1 = E2 then return {}
                else return FAIL;
            E1 is a variable:
                if E1 occurs in E2 then return FAIL
                 else return {E2/E1}
            E2 is a variable
                if E2 occurs in E1 then FAIL
                    else return {E1/E2}
            either E1 or E2 are empty then return FAIL
            otherwise:
                begin
                    HE1 := first element of E1;
                    HE2 := first element of E2;
                    SUBS1 := unify(HE1, HE2);
                    if SUBS1 := FAIL then return FAIL;
                    TE1 := apply(SUBS1, rest of E1);
                    TE2 := apply(SUBS1, rest of E2);
                    SUBS2 := unify(TE1, TE2);
                    if SUBS2 = FAIL then return FAIL;
                         else return composition(SUBS1, SUBS2)
                end
            end

现在我的问题是,如果我有这样的输入: 一个(X,Y)= A(B(C,Y),Z)..

如何提取元素的数量(和值)(即第一个表达式的X和Y)

当我阅读并试图解决这个问题时,我已经为我提出了不同的新技术。  像Lexical Analysis,Parsing我对Lexical Alanysis一无所知,虽然我知道解析和令牌(以String方式)而且我认为它不会解决我的问题.. 我现在正在尝试实施Joey Adams所说的......我认为这对我的问题很有用..

这篇论文的内容...感谢你的帮助

7 个答案:

答案 0 :(得分:5)

你的问题非常笼统,完整的答案可能会在书中占用几个章节。

话虽这么说,我建议你从谷歌搜索开始学习一些术语并了解:

令牌化解析(从字符串中提取单个组件。)

中缀评估(带一对操作数和干预操作员并存储答案)

后缀评估(带一对操作数和一个跟随操作符 - 这还没有意义,但可能会在你读完之后。)

..并进一步阅读:

编译器设计

...当您遇到具体问题时,请继续访问此网站。不要忘记搜索与您的问题相似的问题的答案!

答案 1 :(得分:3)

对于解析简单的数学表达式,我有一个稍微不同寻常但易于实现的解决方案:创建一个二叉树并将每个标记逐个推送到树中。例如:

X

  =
 /
X

  =
 / \
X   1

  =
 / \
X   +
   /
  1

  =
 / \
X   +
   / \
  1   (

  =
 / \
X   +
   / \
  1   (
       |
       12

  =
 / \
X   +
   / \
  1   (
       |
       *
      /
     12

  =
 / \
X   +
   / \
  1   (
       |
       *
      / \
     12  4

  =
 / \
X   +
   / \
  1   (
       |
       +
      /
     *
    / \
   12  4

  =
 / \
X   +
   / \
  1   (
       |
       +
      / \
     *   2
    / \
   12  4

  =
 / \
X   +
   / \
  1   ( )
       |
       +
      / \
     *   2
    / \
   12  4

推送算法是:将新令牌作为子项放在最后插入的令牌的右侧,然后使其浮动直到满足操作顺序(较低的优先级高于优先级较高,并且没有任何内容超过开括号(即'(')直到它关闭(即'(...)')。

以下是我在eC中对此类解析器的实现:http://www.funsitelots.com/pub/ecas0.zip。你需要Ecere SDK来构建它。在PushOperator方法中查看form1.ec。对不起,如果它不是世界上最容易阅读的代码。

答案 2 :(得分:1)

我会看一下Interpreter Design Pattern。谷歌用计算器“模式化”并且有一些不错的命中,例如this one

答案 3 :(得分:0)

您可以采取的一种方法是生成一个可以拉出操作数和运算符的正则表达式。

答案 4 :(得分:0)

您还可以查看一些公式引擎,例如用Java编写的JFormula(还有其他一些)。它们将具有公式所需的语法,并且可能仍然涉及一些解析,但是您将能够通过引擎处理数学表达式和计算顺序。

答案 5 :(得分:0)

这是一个非常糟糕的解决方案,请按照其他人的建议行事 - 阅读该模式。但是,只是为了让这个工作,你可以做一些像

这样的事情
1 - remove all decimals and periods from the input
2 - Use a regular expression to find / remove any parenthesis and the stuff in between them
3 - Use the remaining operations to guess at the number of operands

For example
Your input : 
1+(12*4+2)
1 - remove all #'s and .'s
  +(*+)
2 - remove all ()'s and internals
  +
3 - guess number of operands
  1 operation, so 2 operands

正如我所说,这很糟糕,很容易失败。但是,它可能足以让你入门。在您使用它之后,您将开始发现问题,并希望开始理解为什么需要更强大的解决方案。

HTH

答案 6 :(得分:0)

这是我通过研究@Bob Kaufman的回答找到的一个很棒的链接:

users.cis.fiu.edu/~weiss/dsj2/code/Evaluator.java

这只是代码。 这是一个详细的解释(尽管它使用的是C ++,但逻辑完全相同):http://www.lawrence.edu/fast/greggj/CMSC270/Infix.html