3

В настоящее время я работаю над проектом, используя ArrayStack, чтобы изменить инфикс на постфикс и оценить оценку постфикса. Для первого оператора, который появляется, когда программа читает, он отправляет обратноNullPointerException infix to postfix java using stack

java.lang.NullPointerException 
at InfixToPostfix.convertString(InfixToPostfix.java:27) 
at Postfix.main(Postfix.java:20) 

Я отлажена программа, и я знаю, что придется иметь дело с моим нажимным методом в ArrayStack. Я просто не знаю, как избавиться от NullPointerException.

Это мой класс ArrayStack.

import java.util.*; 

public class ArrayStack<T> implements StackADT<T>{ 

private int top = 0; 
private static final int DEFAULT_CAPACITY = 70; 
private T[] stack; 

@SuppressWarnings("unchecked") 
public ArrayStack() 
{ 
    top = 0; 
    stack = (T[])(new Object[DEFAULT_CAPACITY]); 
} 

@SuppressWarnings("unchecked") 
public ArrayStack (int initialCapacity) 
{ 
    top = 0; 
    stack = (T[])(new Object[initialCapacity]); 
} 

public boolean isEmpty() 
{ 
    if(top==0) 
     return true; 
    else 
     return false; 
} 

public T pop() throws StackIsEmptyException 
{ 
    T retVal; 
    if(isEmpty()) 
     throw new StackIsEmptyException("Stack is Empty"); 
    else{ 
        top--; 
     retVal = stack[top]; 
     } 
    return retVal; 
} 

**public void push (T element) 
{ 
    if (size() == stack.length) 
     expandCapacity(); 
    top++; 
      element = stack[top]; 
}** 

public T peek() throws StackIsEmptyException 
{ 
    if (isEmpty()) 
     throw new StackIsEmptyException("Stack is Empty"); 
    return stack[top-1]; 
} 

@SuppressWarnings("unchecked") 
private void expandCapacity() 
{ 
    T[] larger = (T[])(new Object[stack.length*2]); 
    for (int index=0; index < stack.length; index++) 
     larger[index] = stack[index]; 
    stack = larger; 
} 

@Override 
public String toString() { 
     String result = ""; 
     for (int scan=0; scan < top; scan++) 
     result = result + stack[scan].toString() + "\n"; 
     return result;  
} 
@Override 
public int size() { 
    return top; 
} 
} 

InfixToPostfix Classe

public class InfixToPostfix { 
private ArrayStack<Character> stack; 
private String infix; 
private String postfix= ""; 

public InfixToPostfix(String in, ArrayStack<Character> stack) { 
    infix = in; 
    this.stack = stack; 
} 

@SuppressWarnings("unused") 
public String convertString(){ 
    for (int i = 0; i< infix.length(); i++){ 
     try { 
       char curChar = infix.charAt(i); 
       if(!isOperator(curChar)){ 
        postfix = postfix + curChar; 
        if (i == (infix.length()-1)){ 
         while(!stack.isEmpty()){ 
          postfix += stack.pop();       
         } 
        } 
       }**else if(stack.isEmpty()&& isOperator(curChar)){ 
        stack.push(curChar);** 
       } 
       else if(charPrec(curChar) == 4){ 
        while (!stack.isEmpty() && stack.size() != '('){ 
         postfix += stack.pop(); 
        } 
        stack.pop(); 
       }else if(!(stack.isEmpty())&&(precident(curChar,stack.peek()))){ 
        stack.push(curChar); 
        if(charPrec(stack.peek())==3) 
         stack.push(curChar); 
        while (!(stack.isEmpty())&&(!precident(curChar,stack.peek()))){ 
         postfix += stack.pop(); 
        } 
        stack.push(curChar); 
       }  
      } 
      catch (StackIsEmptyException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
     return postfix; 
    } 

/** 
* Evaluates the specified postfix expression. If an operand is 
* encountered, it is pushed onto the stack. If an operator is 
* encountered, two operands are popped, the operation is 
* evaluated, and the result is pushed onto the stack. 
* @param expr String representation of a postfix expression 
* @return int value of the given expression 
*/ 
public int evaluate (String expr) 
{ 
    int op1, op2, result = 0; 
    String token; 
    StringTokenizer tokenizer = new StringTokenizer (expr); 
    /* while (tokenizer.hasMoreTokens()) 
    { 
     token = tokenizer.nextToken(); 
     if (isOperator(token)) 
     { 
      op2 = (stack.pop()).charValue(); 
      op1 = (stack.pop()).charValue(); 
      result = evalSingleOp (token.charAt(0), op1, op2); 
      stack.push (new Integer(result)); 
     } 
     else 
      stack.push (new Integer(Integer.parseInt(token))); 
    } */ 
return result; 
} 
/** 
* Determines if the specified token is an operator. 
* @param token String representing a single token 
* @return boolean true if token is operator 
*/ 
private boolean isOperator (String token) 
{ 
return (token.equals("+") || token.equals("-") || 
token.equals("*") || token.equals("/")); 
} 
/** 
* Performs integer evaluation on a single expression consisting of 
* the specified operator and operands. 
* @param operation operation to be performed 
* @param op1 the first operand 
* @param op2 the second operand 
* @return int value of the expression 
*/ 
private int evalSingleOp (char operation, int op1, int op2) 
{ 
    int result = 0; 
    switch (operation) 
{ 
    case '+': 
     result = op1 + op2; 
     break; 
    case '-': 
     result = op1 - op2; 
     break; 
    case '*': 
     result = op1 * op2; 
     break; 
    case '/': 
     result = op1/op2; 
} 
    return result; 
} 


private boolean isOperator(char ch) { 
    if(ch=='/'||ch=='*'||ch=='+'||ch=='-') 
     return true; 
    else 
     return false; 
    } 


private boolean precident(char one, char two) { 
    if(charPrec(one) >= charPrec(two)); 
     return true; 
} 
private int charPrec(char ch) { 
    switch(ch) { 
     case '-': 
      return 1; 
     case '+': 
      return 1; 
     case '*': 
      return 2; 
     case '/': 
      return 2; 
     case '(': 
      return 3; 
     case ')': 
      return 4; 
    } 
    return 0; } 
    } 

ответ

0

Есть несколько проблем в вашем коде ... Heres те, которые я вижу:

  1. когда же размер() метод никогда не возвращает символ стоимость? size() - действительно плохое имя метода.
  2. Весь ArrayStack<T> implements StackADT<T> класс должен, вероятно, CharacterStack implments StackADT<Character> которые упростили бы много вещей
  3. Эта линия, которую я считаю, это на линии 27 (где ваш NullPointer есть), есть: stack.size() != '(' но это делает мало или нет смысла ... .. хотя он не будет указывать нулевой указатель.
  4. Вы не укажете, в какой строке возникла проблема - отметьте ее в действительном коде, чтобы мы могли ее увидеть, и не должны сами подсчитывать линии.

Метод кода и названия переменных делают чтение очень сложным. Исправьте свои соглашения об именах, отредактируйте и повторите попытку.

Я предполагаю, что если вы переработали код, вы сами найдете проблему.

+1

Ну, я назвал массив массива с его стеком, который использует массив вместо связанного списка. Но я только что отредактировал его, поскольку метод размера не имел смысла и имел его, как я его первоначально имел. Нулевой указатель предназначен для метода push под первым elseif в методе convertString. –