首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:空指针去队列迭代器

Java:空指针去队列迭代器
EN

Stack Overflow用户
提问于 2015-04-20 11:20:03
回答 2查看 224关注 0票数 2

我被指派编写一个类,该类接受中缀表示法中的数学表达式,并将该表达式转换为后缀表示法中的等效表达式。这部分我已经完成了。

我还被指派编写一个迭代器,让客户端代码遍历后缀表达式的标记。

所以,到目前为止,我的迭代器的代码是:

代码语言:javascript
复制
class PostfixIterator implements Iterator<String> { //this is line 117

private Deque<String> postfix;

public PostfixIterator(Deque<String> postfix) {
    this.postfix = postfix;
}

public boolean hasNext() {
    return postfix.isEmpty();
}

public String next() {
    return postfix.pop(); //this is line 130
}

}

当我尝试创建我的迭代器的一个实例并调用其中一个方法时,我得到一个空指针异常,并且我不知道为什么。

下面是我的main的样子:

代码语言:javascript
复制
public static void main(String[] args){
    InfixToPostfix a = new InfixToPostfix("(123)^45+6*7/89");
    Iterator itr = a.iterator();
    System.out.println(itr.next());

}

根据我的编译器,return postfix.pop()的计算结果为null。不过,我不知道为什么。

那么,有没有人可以帮我解决这个问题,并可能解释一下为什么我现在的东西不能工作?

谢谢

下面是我的整个InfixToPost修复类:

代码语言:javascript
复制
import java.util.*;

public class InfixToPostfix{

    private Deque<String> postfix;

    public InfixToPostfix(String infix){

        Deque<String> postfix = new LinkedList<String>();
        Deque<String> infixQ = new LinkedList<String>();

        //tokenize the user input
        int i = 0;
        char ch;
        infix = infix.replaceAll("\\s","");//make sure there is no whitespace
         while(i < infix.length()){
             ch = infix.charAt(i);

             if(ch == '(' || ch == ')'|| ch == '+'|| ch == '-' 
                     || ch == '/' || ch == '%'|| ch == '*' 
                     || ch == '^'){
                 String s =ch+"";
                 infixQ.add(s);
                 i++;
             }
             else if (Character.isDigit(ch)){
                 String s ="";
                 int j = i;
                 char c = infix.charAt(j);
                 while(j <= infix.length()-1 && //accumulate the digits in that number
                       Character.isDigit(c = infix.charAt(j))){
                     s = s + c;
                     j++;
                 }
                 infixQ.add(s);
                 i=j;
             }
             else if (Character.isLetter(ch)){
                 String s ="";
                 int j = i;
                 char c = infix.charAt(j);
                 while(j <= infix.length()-1 && //accumulate the lettes in that variable
                       Character.isLetter(c = infix.charAt(j))){
                     s = s + c;
                     j++;
                 }
                 infixQ.add(s);
                 i=j;
             }
        }
        System.out.println(infixQ);

        //start shunting-yard
        Deque<String> stack = new ArrayDeque<String>();
        Iterator<String> itr = infixQ.iterator();
        while(itr.hasNext()){
            String s = itr.next();

            //if token is number or a variable, put it on the output queue
            if(Character.isDigit(s.charAt(0)) 
               || Character.isLetter(s.charAt(0))){
                postfix.add(s);
            }
           if(s.equals("(")){
                stack.push(s);
            }
            if(s.equals(")")){
                while((!stack.isEmpty())&&(!stack.peek().equals("("))){
                    postfix.add(stack.pop());
                }
                stack.pop();
            }
            if(s.equals("+") || s.equals("-")){
                while((!stack.isEmpty()) && (stack.peek().equals("+") 
                     || stack.peek().equals("-")
                     || stack.peek().equals("*") || stack.peek().equals("/")
                     || stack.peek().equals("^"))){
                     postfix.add(stack.pop());

                }
                stack.push(s);
            }
            if(s.equals("*") || s.equals("/") || s.equals("%")){
                if(!stack.isEmpty()){
                    while((!stack.isEmpty())&&(stack.peek().equals("*") 
                          || stack.peek().equals("/") 
                          || stack.peek().equals("%")
                          || stack.peek().equals("^"))){
                        postfix.add(stack.pop());            
                    }
                }
                stack.push(s);
            }
            if(s.equals("^")){
                stack.push(s);
            }       
        }
        while(!stack.isEmpty()){
            postfix.add(stack.pop());
        }
        System.out.println(stack.isEmpty());
        System.out.println(postfix);        
    }

    public Iterator<String> iterator(){
        return new PostfixIterator(postfix);
    }

    public static void main(String[] args){
        InfixToPostfix a = new InfixToPostfix("(123)^45+6*7/89");
        Iterator itr = a.iterator();
        System.out.println(itr.next()); // this is line 112

    }
    }

我敢肯定它写得很糟糕。我只想让它正常工作,这样我就可以上交它了。

下面是我的堆栈跟踪:

代码语言:javascript
复制
Exception in thread "main" java.lang.NullPointerException
at PostfixIterator.next(InfixToPostfix.java:130)
at PostfixIterator.next(InfixToPostfix.java:117)
at InfixToPostfix.main(InfixToPostfix.java:112)
EN

回答 2

Stack Overflow用户

发布于 2015-04-20 11:52:42

您的问题与数据字段postfix的作用域有关

这就是你所拥有的:

代码语言:javascript
复制
public class InfixToPostfix{

    private Deque<String> postfix; <-- this is data field 

    public InfixToPostfix(String infix){

        Deque<String> postfix = new LinkedList<String>();
                         ^
                         |   
you declared that reference here again which shadows the data field. 
postfix is just visible in constructor and out of here your data field
is still pointing to null value.

将其更改为

代码语言:javascript
复制
postfix = new LinkedList<String>(); 

因此,您将实例化后缀,当您想要访问它时,它永远不会是null,因为您实例化了数据字段postfix

一些建议:

  1. 您可以使用菱形推理 Java 7

例如:

代码语言:javascript
复制
 List<String> myList = new ArrayList<String>();

可以写入

代码语言:javascript
复制
  List<String> myList = new ArrayList< >();
                                      ^
                                      |

如果您可以在下面的代码中为您的迭代器函数选择不同的名称,这会更好,因为您可能会使阅读您代码的人感到困惑

代码语言:javascript
复制
public Iterator<String> iterator(){
        return new PostfixIterator(postfix);
    }
票数 4
EN

Stack Overflow用户

发布于 2015-04-20 11:41:54

似乎你声明了两次变量"postfix“,你应该只使用类变量"postfix”。

代码语言:javascript
复制
public class InfixToPostfix{

   private Deque<String> postfix;

   public InfixToPostfix(String infix){

        postfix = new LinkedList<String>();
        // Code here
   }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29738808

复制
相关文章

相似问题

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