0

我正在实施调车场算法,但在处理括号时遇到了麻烦。不过,它适用于非分组表达式。这是我没有括号检测的情况:

public void makePost(String e)
{
    String[] arr = e.split("");
    for(int i = 0; i < arr.length; i++)
    {
        if(arr[i].equals(" "))
        {
            continue;
        }
        Operator o = OperatorList.getOpMap().get(arr[i]);
        if(o == null){
            postfix += " " + arr[i];
            continue;
        }
        if(ops.isEmpty()){
            ops.push(o);
            continue;
        }
        else
        {

            while((!ops.isEmpty()  && (ops.peek().getPresedence() <= o.getPresedence()))){
                postfix += " " + ops.pop();
            }
            ops.push(o);
            continue;
        }

    }
    while(!ops.isEmpty())
    {
        postfix += " " + ops.pop();
    }
    postfix = postfix.trim();

}

ops 是保存 Operator 对象的堆栈。有两种类型的运算符,函数(+,-,*等)和Parans(“(”,“[”))。您如何为此添加括号处理?每次尝试,我似乎都无法理解正常工作

这是我尝试过的:

    public void makePost(String e)
{
    String[] arr = e.split("");
    for(int i = 0; i < arr.length; i++){
        if(arr[i].equals(" ")){
            continue;
        }
        Operator o = OperatorList.getOpMap().get(arr[i]);
        if(o == null){
            postfix += " " + arr[i];
            continue;
        }
        if(ops.isEmpty()){
            ops.push(o);
            continue;
        }
        else
        {
            if(o.isParan())
            {
                Paran p = new Paran(o.toString());
                if(p.isOpen())
                {
                ops.push(o);
                System.out.println(ops);
                continue;
                }else{      
                    while(!ops.isEmpty()){ 
                        if(ops.peek().isParan()){
                            Paran n = new Paran(o.toString());
                            if(n.isOpen()){
                                ops.pop();
                                break;
                            }
                        }
                        postfix += " " + ops.pop();
                    }
                    continue;
                }
            }
            while((!ops.isEmpty()  && (ops.peek().getPresedence() <= o.getPresedence()))){
                postfix += " " + ops.pop();
            }
            ops.push(o);
            continue;
        }

    }
    while(!ops.isEmpty())
    {
        postfix += " " + ops.pop();
    }
    postfix = postfix.trim();

}

我怀疑while循环条件不好,但我不知道有什么合适的替换。它继续到无穷大。这是我拥有的最干净的实现。基本上它应该做的是当它遇到一个左括号时,将它压入堆栈。当它碰到一个闭合的时,将堆栈中的所有内容弹出到输出上,直到它碰到左括号。然后它应该中断,并继续下一个令牌。

if(o.isParan())
            {
                Paran p = new Paran(o.toString());
                if(p.isOpen())
                {
                ops.push(o);
                System.out.println(ops);
                continue;
                }else{      
                    while(!ops.isEmpty()){ 
                        if(ops.peek().isParan()){
                            Paran n = new Paran(o.toString());
                            if(n.isOpen()){
                                ops.pop();
                                break;
                            }
                        }
                        postfix += " " + ops.pop();
                    }
                    continue;
                }

编辑:添加了我的尝试

4

1 回答 1

0

让它工作!我在逻辑区域添加了一些括号检查,这是最后的:

    public void makePost(String e)
{
    String[] arr = e.split("");
    for(int i = 0; i < arr.length; i++)
    {

        System.out.println(postfix + " " + i + " " + ops);
        if(arr[i].equals(" "))
        {
            continue;
        }
        if(arr[i].equals("(")){
            ops.push(new Paran("("));
            continue;
        }
        if(!ops.isEmpty() && arr[i].equals(")")){
            while(!ops.isEmpty() && !ops.peek().isOpen()){

                postfix += " " + ops.pop();
            }
            ops.pop();
        }
        Operator o = OperatorList.getOpMap().get(arr[i]);
        if(o == null){
            postfix += " " + arr[i];
            continue;
        }
        if(ops.isEmpty()){

            ops.push(o);

            continue;
        }
        else
        {

            while((!ops.isEmpty()  && (ops.peek().getPresedence() <= o.getPresedence()) && !(ops.peek() instanceof Paran))){

                postfix += " " + ops.pop();
            }
            ops.push(o);
            continue;

        }

    }

    while(!ops.isEmpty())
    {

        postfix += " " + ops.pop();
    }

   postfix = postfix.replaceAll("\\s[)]","");


}

我有 replaceall() 调用,因为输出一直返回右括号以及正确的后缀,例如:

2 4 * 7 8 4 * 4 4 5 * ) / ) * ) +

我不知道为什么会这样,但我很高兴它有效

于 2014-01-05T02:47:26.713 回答