Java中给出错误输出和字符串索引超出范围的调车场算法实现



我正在实现调车场算法并评估结果这是一个基于参考的实现,使用了节点(一个用于运算符,一个用于操作数)和堆栈(一个用作运算符,另一个用于运算数)。


输入文件包含(仅前几行):

5
5-3
5*(3+4)
7*3+5*6
2+5*(7+8)/3

输出:

53 = 53
53513 = 1
535152
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: 
String index out of range: 7
    at java.lang.String.charAt(String.java:646)
    at LabIII.main(LabIII.java:48)
Process completed.

Main:

public class LabIII
{
public static String expr;
public static String line;
public static void main(String[] args) throws IOException
{       
    try
    {
        BufferedReader input = new BufferedReader(new FileReader("input.txt")); // Create input reader
        char token;
        int tokenI;
        char popOp;
        int popInt1;
        int popInt2;
        int result;
        while ((line = input.readLine()) != null) // While the input file still has a line with characters
        {
            operatorStack opStack = new operatorStack(); // Initalize the operator stack
            opStack.push(';');
            operandStack intStack = new operandStack();
            expr = line;
            int count = 1;
            while(count <= expr.length())
            {
                int index = count - 1;
                if(Character.isDigit(expr.charAt(index))) // If token is an operand
                {
                    tokenI = expr.charAt(index);
                    System.out.print(tokenI);
                    intStack.push(tokenI);
                    count++;
                }
                else
                {
                    token = expr.charAt(count);
                    if(token == ')')
                    {   
                        while(opStack.peek() != '(')
                        {
                            popOp = opStack.pop();
                            System.out.print(popOp);
                            popInt1 = intStack.pop();
                            popInt2 = intStack.pop();
                            result = evaluate(popInt1, popInt2, popOp);
                            intStack.push(result);                          
                        }
                        opStack.pop(); // Pop the "(" and discard it
                        count++;
                    }
                    else
                    {
                        while(inputPriority(token) <= stackPriority(opStack.peek()))
                        {
                            popOp = opStack.pop();
                            System.out.print(popOp);
                            popInt1 = intStack.pop();
                            popInt2 = intStack.pop();
                            result = evaluate(popInt1, popInt2, popOp);
                            intStack.push(result);
                        }
                        opStack.push(token);
                        count++;
                    }
                }
            }
            while (opStack.peek() != ';')
            {
                popOp = opStack.pop();
                System.out.print(popOp);
                popInt1 = intStack.pop();
                popInt2 = intStack.pop();
                result = evaluate(popInt1, popInt2, popOp);
                intStack.push(result);
            }
            System.out.print(" = " + intStack.pop());
            System.out.println();
            count = 0;              
        }
    }
    catch (IOException ex)
    {
        System.err.println("Exception:" + ex);
    }
}
}

operatedStack(也是operatorStack的一个。相同,只是使用char而不是int):

public class operandStack
{
    int integ;
    NodeInt top;
    NodeInt temp;
    public operandStack() // Default constructor: empty stack
    {
        top = null;
    }
    public boolean isEmpty() // Returns true if the top of the stack is null
    {
        return top == null;
    }
    public void push(int integ) // Push an item onto the top of the stack
    {
        top = new NodeInt(integ, top);
    }
    public int pop()
    {
        NodeInt temp = top;
        top = top.getNext();
        return temp.getItem();
    }
    public void popAll()
    {
        top = null;
    }
    public int peek()
    {
        return top.getItem();
    }       
}

节点(也是一个用于操作数/整数的节点):

public class Node{
private char item;
private Node next;
public Node(char newItem)
{
    item = newItem;
    next = null;
}
public Node(char newItem, Node nextNode)
{
    item = newItem;
    next = nextNode;
}
public char getItem()
{
    return item;
}
public void setNext(Node nextNode)
{
    next = nextNode;
}
public Node getNext()
{
    return next;
}
}

算法如下:

初始化运算符堆栈以包含";"(栈底操作员)

获取第一个代币

而表达式的末尾未达到

如果令牌是操作数,则

打印代币

将操作数推送到操作数堆栈

否则,如果令牌是")",则

而操作员堆栈的顶部不等于"("

弹出操作员堆栈

打印操作员

弹出操作数堆栈两次

将指定操作应用于两个操作数

将运算结果推送到操作数堆栈

结束时

弹出"("并丢弃

其他

当inputPriority(令牌)≤stackPriority时(操作员堆栈顶部)

弹出操作员堆栈

打印操作员

弹出操作数堆栈两次

将指定操作应用于两个操作数

将运算结果推送到操作数堆栈

结束时

将令牌推到操作员堆栈上

获取下一个代币

结束时

而运算符堆栈的顶部不等于";"

弹出操作员堆栈

打印操作员

弹出操作数堆栈两次

将指定操作应用于两个操作数

将运算结果推送到操作数堆栈

结束时

弹出操作数堆栈并打印结果

感谢您的帮助。

token = expr.charAt(count);

这应该是

token = expr.charAt(index);

我不知道你为什么要同时维护indexcount.。这只会导致这样的麻烦。

我发现了问题。还有另外两个问题:

首先,输入文件的末尾有两行额外的空行,这导致了异常。

其次,tokenI = expr.charAt(index)将ASCII值分配给tokenI(例如,输入值5导致tokenI为53),所以我只需要减去48(0的ASCII值)来纠正这个问题。tokenI = expr.charAt(index) - 48在那之后,一切都安排好了。

此外,正如@EJP所说,不需要同时使用"index"one_answers"count"变量,所以我去掉了"count",只使用了"index"。

相关内容

  • 没有找到相关文章

最新更新