首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java RPN (反向波兰符号)注入到后缀

Java RPN (反向波兰符号)注入到后缀
EN

Stack Overflow用户
提问于 2009-08-24 07:16:47
回答 2查看 26.1K关注 0票数 5

我非常肯定,堆栈用于构建PRN和“(”)被忽略,但情况似乎并非如此。例如:

  • 输入1: 52+(1+2)*4-3
  • 输入2: 52+((1+2)*4)-3
  • 输入3: (52+1+2)*4-3

输入1和输入2输出应该相同,输入1和输入3应该不同。

  • 输出1: 52 1 2+4 3-*+
  • 输出2: 52 1 2+4*3-+
  • 输出3: 52 1 2+4 3-*+
代码语言:javascript
复制
    public static String Infix2(String input) {
        char[] in = input.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        StringBuilder out = new StringBuilder();

        for (int i = 0; i < in.length; i++)
            switch (in[i]) {
            case '+':
            case '*':
            case '-':
                out.append(' ');
                stack.push(in[i]);
                break;
            case ' ':
            case '(':
                break;
            case ')':
                out.append(' ');
                out.append(stack.pop());
                break;
            default:
                out.append(in[i]);
                break;
            }

        while (!stack.isEmpty()) {
            out.append(' ');
            out.append(stack.pop());
        }

        return out.toString();
    }

假设我希望输入1和3也能工作,我应该使用什么方法?

编辑:在更改“+”、“-”、“*”和“/”之后,对给定的输入进行修改。

代码语言:javascript
复制
public static String Infix2(String input) {
    if (input == null)
        return "";
    char[] in = input.toCharArray();
    Stack<Character> stack = new Stack<Character>();
    StringBuilder out = new StringBuilder();

    for (int i = 0; i < in.length; i++)
        switch (in[i]) {
        case '+':
        case '-':
            while (!stack.empty()
                    && (stack.peek() == '*' || stack.peek() == '/'))
                out.append(' ').append(stack.pop());
        case '*':
        case '/':
            out.append(' ');
        case '(':
            stack.push(in[i]);
        case ' ':
            break;
        case ')':
            while (!stack.empty() && stack.peek() != '(')
                out.append(' ').append(stack.pop());
            if (!stack.empty())
                stack.pop();
            break;
        default:
            out.append(in[i]);
            break;
        }

    while (!stack.isEmpty())
        out.append(' ').append(stack.pop());

    return out.toString();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-08-24 08:49:11

算法非常简单(和这里有一个很好的解释)。每个操作都有一个绑定权重,+和-是最低的.有两条规则:

  • 立即打印数字
  • 不要把较轻的东西放在较重的物品上。
  • 左圆括号放在堆栈上
  • 右括号从堆栈中弹出,直到碰到左括号,然后删除左括号。

对于第一个示例,52+(1+2)*4-3,下面是堆栈:

代码语言:javascript
复制
 52+          => +
 52+(         => + (
 52+(1+       => + ( + 
 52+(1+2)     => +       //right parentheses popped +
 52+(1+2)*4   => + * 
 52+(1+2)*4-3 => + -     //can't put - on top of *, so pop off *
 ... and then pop the stack until it's empty.

将您的开关循环替换为下面的(与您所拥有的最接近的模拟)将为您的三个示例提供正确的答案。在真正的解析器中,您将给每个操作符一个权重,并概括pop机制。

代码语言:javascript
复制
for (int i = 0; i < in.length; i++)
        switch (in[i]) {
        case '+':
        case '-':
            while (!stack.empty() && (stack.peek() == '*' || stack.peek() == '/')) {
                out.append(' ');
                out.append(stack.pop());
            }
            out.append(' ');
            stack.push(in[i]);
            break;
        case '*':
        case '/':
            out.append(' ');
            stack.push(in[i]);
            break;
        case '(':
            stack.push(in[i]);
            break;
        case ')':
            while (!stack.empty() && stack.peek() != '(') {
                out.append(' ');
                out.append(stack.pop());
            }
            stack.pop();
            break;
        default:
            out.append(in[i]);
            break;
        }
票数 13
EN

Stack Overflow用户

发布于 2009-08-24 08:50:42

对于具体的问题,不是一个确切的答案,而是我建议开发这类算法的东西:看看测试驱动开发(TDD)。简单地说:为infix2方法编写几个单元测试(例如用infix2 ),如果infix2生成正确的输出,您可以为该方法提供测试模式(表达式)和测试。

从简单的开始,比如

代码语言:javascript
复制
assertequals("1", "1"); // positive number
assertequals("-1", "-1"); // negative number
assertequals("1+1", "1 1 +"); // simple addition
assertequals(" 1 + 1 ", "1 1 +"); // simple addition with whitechars
assertequals(" 1 + +1 ", "1 -1 +"); // simple addition with pos. number & whitechars
assertequals(" 1 + -1 ", "1 -1 +"); // simple addition with neg. number & whitechars
assertequals("(1+1)", "1 1 +"); // simple addition with brackets

别忘了像这样的非法表达

代码语言:javascript
复制
String[] illegalExpressions = {null, "", " ", "1 +", "1 + 1)"};

您的示例的测试用例应该是

代码语言:javascript
复制
assertequals("52+(1+2)*4-3", "52 1 2 + 4 * 3 -");
assertequals("52+((1+2)*4)-3", "52 1 2 + 4 * 3 -");
assertequals("(52+1+2)*4-3", "52 1 + 2 + 4 * 3 -");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1320891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档