我被指派编写一个类,该类接受中缀表示法中的数学表达式,并将该表达式转换为后缀表示法中的等效表达式。这部分我已经完成了。
我还被指派编写一个迭代器,让客户端代码遍历后缀表达式的标记。
所以,到目前为止,我的迭代器的代码是:
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的样子:
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修复类:
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
}
}我敢肯定它写得很糟糕。我只想让它正常工作,这样我就可以上交它了。
下面是我的堆栈跟踪:
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)发布于 2015-04-20 11:52:42
您的问题与数据字段postfix的作用域有关
这就是你所拥有的:
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.将其更改为
postfix = new LinkedList<String>(); 因此,您将实例化后缀,当您想要访问它时,它永远不会是null,因为您实例化了数据字段postfix。
一些建议:
Java 7 例如:
List<String> myList = new ArrayList<String>();可以写入
List<String> myList = new ArrayList< >();
^
|如果您可以在下面的代码中为您的迭代器函数选择不同的名称,这会更好,因为您可能会使阅读您代码的人感到困惑
public Iterator<String> iterator(){
return new PostfixIterator(postfix);
}发布于 2015-04-20 11:41:54
似乎你声明了两次变量"postfix“,你应该只使用类变量"postfix”。
public class InfixToPostfix{
private Deque<String> postfix;
public InfixToPostfix(String infix){
postfix = new LinkedList<String>();
// Code here
}
}https://stackoverflow.com/questions/29738808
复制相似问题