使用实数(正数和负数)对中缀进行后缀

时间:2013-03-19 20:23:27

标签: java

我编写了一个程序,允许从中缀到后缀表达式进行翻译,但它只适用于一个数字[A-Z][a-z][0-9]。我怎样才能使真实(正面和负面)数字成为可能?

Example: (50 + 3.75) + 50 --> 50 3.75 + 50 +

doTrans()允许从中缀到后缀的翻译

public String doTrans() {
        for (int j = 0; j < input.length(); j++) {
            char ch = input.charAt(j);
            theStack.displayStack("For " + ch + " ");
            switch (ch) {
            case '+':
            case '-':
                gotOper(ch, 1);
                break;
            case '*':
            case '/':
                gotOper(ch, 2);
                break;
            case '(':
                theStack.push(ch);
                break;
            case ')':
                gotParen(ch);
                break;
            default:
                output = output + ch;
                break;
            }
        }
        while (!theStack.isEmpty()) {
            theStack.displayStack("While ");
            output = output + theStack.pop();
        }
        theStack.displayStack("End ");
        return output;
    }

此行中的问题output = output + ch;。我找不到如何获得整数而不是一个数字的解决方案

1 个答案:

答案 0 :(得分:1)

你必须做Lexical analysis。您必须将输入流转换为令牌并对其进行分类。目前您的程序已经完成,但它非常基础,那么您的令牌只包含一位数。虽然令牌可能更复杂,从大于9的简单整数数字文字,浮点数字面值,字符串文字,简单运算符等开始。

您现在可能拥有的是在后续调用中为您提供分析处理它并下一步的下一个令牌。类似的东西:

String input = "1 + 2";
int actPos = 0 ;

....

char getNextToken() {
    return input.charAt(actPos++);
}

你需要做的是重写getNextToken(),以便它给你一个“复杂”的令牌(由多个数字/字符组成,因此是一个字符串)你必须在下一个分类步骤

String getNextToken() {
    String StringBuilder token = new StirngBuilde();

    // extract the next token from the input stream
    // using a state automata witch comes to a final
    // state when a token was recognized or an erroneous input

    return token.toString();
}

<强> EIDT

您需要编写finite state machine来分析输入流并生成令牌。

只是给你一个非常简单的例子(假设你已经阅读了上面链接中的定义),假设你有字母{'0','1','2','3','4','5','6','7','8','9'},并且想要构建没有符号的整数标记。您将整数定义为[0-9]+

你的状态机需要至少三个状态START女巫是开始状态,INTEGER女巫是最终和接受状态,ERROR女巫表示存在错误输入。

现在你需要一个转换函数和一个state transition table,这是实际输入并根据实际状态产生下一个状态的。

状态转换表可能看起来像那样(非常基本,在没有输入时无法处理)

              i n p u t
              +----------+----------+
              | [0-9]    | else     |
s  +----------+----------+----------+
t  | START    | INTEGER  | ERROR    |
a  +----------+----------+----------+
t  | INTEGER  | INTEGER  | ERROR    |
e  +----------+----------+----------+
   | ERROR    | ERROR    | ERROR    |
   +----------+----------+----------+

因此,假设您有以下输入:27

  • 开始时状态机的状态为START(实际状态)
  • 您阅读了第一个字符2,并将其与实际状态一起传递给转换函数
  • 由于2是一个整数,因此您的函数会将您带到状态INTEGER,因为这不是ERROR,所以您将它放在缓冲区中,您可以通过char构建令牌char。
  • 现在,您阅读了下一个字符7,并将其与实际状态INTEGER一起传递给转换函数。
  • 7也是一个整数,与2相同。
  • 现在,令牌缓冲区的内容为27,状态机仍然处于状态INTEGER,这是一个接受状态,没有输入。此时,您可以将令牌缓冲区的内容作为下一个令牌返回。

现在假设你有输入:2e7

你的状态机如上所述继续使用第一个字符2和状态INTEGER,然后来e不符合上面定义的整数的规则({{1} })。将[0-9]+与实际状态e一起传递到转换函数会导致转换状态INTEGER。此时,您可以通知ERROR的位置/索引处的输入中存在错误。

我建议你阅读更多关于词法分析以及如何编写有限状态机来实现它。

有人说过,你总是可以使用JLex之类的工具来为你生成这个分析代码,但是你仍然必须为它定义一些规则来生成你希望它做的代码,女巫带你回到阅读有关词法分析的更多信息:)

祝你好运!