首页 > 解决方案 > 使用导致 NullPointerException 的字符串填充 ArrayDeques

问题描述

你好,这里的菜鸟。

我目前正在尝试为 post-fix 计算器程序编写一个 in-fix,当我尝试清理冗余代码时,我发现根据我构建 ArrayDeque 的方式,即使数组在内容。我首先使用“.add()”重复填充了我的 ArrayDeque,效果很好,但是我尝试使用字符串来清理它(所以我可以更有效地测试方程)所有这些都在下面的测试类中完成。我还留下了一些可能对你们有用的评论。

import java.math.BigInteger;
import java.util.ArrayDeque;
import java.util.Deque;

public class EvaluatorTest {
    public static void main(String[] args) {
        ArrayDeque < String > inFixEquation1 = new ArrayDeque < > ();
        ArrayDeque < String > inFixEquation2 = new ArrayDeque < > ();

        // Non DRY code: This for some reason doesnt work.
        String equation = "A*(B+C)";
        int temp = equation.length();
        for (int i = 0; i < temp; i++) {
            inFixEquation1.add(equation.substring(0, 1));
            equation = equation.substring(1, equation.length());
        }

        // DRY code: While this does work.
        inFixEquation2.add("A");
        inFixEquation2.add("*");
        inFixEquation2.add("(");
        inFixEquation2.add("B");
        inFixEquation2.add("+");
        inFixEquation2.add("C");
        inFixEquation2.add(")");

        System.out.println("\nCreated inFix equation 1 = " + inFixEquation1);
        System.out.println("Created inFix equation 2 = " + inFixEquation2);

        Deque < String > postFixEquation = Evaluator.infixToPostfix(inFixEquation1); // I switch between the first and second inFixEquations here jsut by changing inFixeEquation1 to inFixEquation2
        System.out.println("\nConverted inFix equation to postFix = " + postFixEquation);
        System.out.println("postFix answer should equal =         [A, B, C, +, *]");
        BigInteger evaluated = Evaluator.evalPostfix(postFixEquation);
        System.out.println("Evaulated postFix equation to BigInteger " +
                "value = " + evaluated + "\n\nProgram end.");
    }
}

我也为混乱的代码道歉,就像我说的,我正在清理代码。下面的代码是进行实际转换的类。

import java.math.BigInteger;
import java.util.*;

public class Evaluator {

    public static Deque < String > infixToPostfix(Deque < String > in ) {
        Deque < String > inFix = new ArrayDeque < String > ( in ); 
        Deque < String > postFix = new ArrayDeque < > (); 
        Stack < String > storedOperators = new Stack(); 
        Set < String > allOperators = new HashSet < > 
                (Arrays.asList("*", "/", "%", "+", "-", ")", "(")); 

        for (int i = 0; i < in .size(); i++) {
            if (!allOperators.contains(inFix.peek())) {
                postFix.add(inFix.pop());
            } else if (allOperators.contains(inFix.peek())) { 
                if (inFix.peek() == "(" || storedOperators.size() == 0 && inFix.peek() != ")") { 
                    storedOperators.add(inFix.pop()); 
                } else if (inFix.peek() == ")") { // The compiler seems to skip here when inFix.peek() equals ")" if I'm using the first ArrayDeque but not the second.
                    while (storedOperators.peek() != "(")
                        postFix.add(storedOperators.pop());
                    if (storedOperators.peek() == "(")
                        storedOperators.pop();
                } else if (priorityCheck(inFix.peek(), storedOperators.peek())) {
                    while (inFix.size() > 0 && storedOperators.size() > 0 && priorityCheck(inFix.peek(), storedOperators.peek()))
                        postFix.add(storedOperators.pop()); 
                    storedOperators.add(inFix.pop());
                } else if (!priorityCheck(inFix.peek(), storedOperators.peek())) {
                    storedOperators.add(inFix.pop());
                }
            }
        }

        for (int i = storedOperators.size(); i > 0; i--)
            postFix.add(storedOperators.pop());
        return postFix;
    }

    public static boolean priorityCheck(String inFix, String auxOp) {
        boolean answer = false;
        Map < String, Integer > opPriority = new HashMap < > () {
            {
                put("-", 1);
                put("+", 2);
                put("^", 3);
                put("/", 4);
                put("*", 5);
                put("(", 1);
            }
        };
        if (opPriority.get(inFix) < opPriority.get(auxOp))
            answer = true;
        return answer;
    }
}

因此,如果我使用测试类中的第一个 ArrayDeque 方程运行,我会得到这个错误,而第二个会运行良好,你们知道这是为什么吗?我知道空指针来自哪里以及为什么它来自这个特定的地方,但我想我主要想知道为什么我的程序没有捕捉到我的第二类第 19 行的最后一个“)”括号,当它不这样做时当我手动构建没有 for 循环和字符串的 ArrayDeque 时的方式。

Created inFix equation 1 = [A, *, (, B, +, C, )]
Created inFix equation 2 = [A, *, (, B, +, C, )]
Exception in thread "main" java.lang.NullPointerException
at Evaluator.priorityCheck(Evaluator.java:61)
at Evaluator.infixToPostfix(Evaluator.java:25)
at EvaluatorTest.main(EvaluatorTest.java:31)

标签: java

解决方案


opPriority地图错过运营商,)可以设置)优先级为1,如:

Map<String, Integer> opPriority = new HashMap<String, Integer>() {
    {
        put("-", 1);
        put("+", 2);
        put("^", 3);
        put("/", 4);
        put("*", 5);
        put("(", 1);
        put(")", 1);
    }
};

然后EvaluatorTest输出如下:

Created inFix equation 1 = [A, *, (, B, +, C, )]
Created inFix equation 2 = [A, *, (, B, +, C, )]

Converted inFix equation to postFix = [A, *, B, C, +, ), (]
postFix answer should equal =         [A, B, C, +, *]

更新

对于inFixEquation1which 运行不正确,这是由您比较两个字符串的方式引起的。

对于字符串值比较,您应该使用oneStr.equals(otherStr)而不是==. 这==意味着比较字符串对象引用而不是字符串值。正确的方法如下:

public static Deque<String> infixToPostfix(Deque < String > in) {
    Deque < String > inFix = new ArrayDeque< String >(in );
    Deque < String > postFix = new ArrayDeque < > ();
    Stack< String > storedOperators = new Stack();
    Set< String > allOperators = new HashSet< >
        (Arrays.asList("*", "/", "%", "+", "-", ")", "("));

    for (int i = 0; i < in .size(); i++) {
        if (!allOperators.contains(inFix.peek())) {
            postFix.add(inFix.pop());
        } else if (allOperators.contains(inFix.peek())) {
            if (inFix.peek().equals("(") || storedOperators.size() == 0 && !inFix.peek().equals( ")")) {
                storedOperators.add(inFix.pop());
            } else if (inFix.peek().equals(")")) {
                while (!storedOperators.peek().equals("("))
                    postFix.add(storedOperators.pop());
                if (storedOperators.peek().equals("("))
                    storedOperators.pop();
            } else if (priorityCheck(inFix.peek(), storedOperators.peek())) {
                while (inFix.size() > 0 && storedOperators.size() > 0 && priorityCheck(inFix.peek(), storedOperators.peek()))
                    postFix.add(storedOperators.pop());
                storedOperators.add(inFix.pop());
            } else if (!priorityCheck(inFix.peek(), storedOperators.peek())) {
                storedOperators.add(inFix.pop());
            }
        }
    }

    for (int i = storedOperators.size(); i > 0; i--)
        postFix.add(storedOperators.pop());
    return postFix;
}

推荐阅读