2016-02-16 32 views
1

我正在试图使用ArrayStack作一个算术计算器。它的工作方式是,它需要一个txt文件,它有一堆表达式,并扫描每一行。对于扫描的每一行,它都会复制表达式及其结果,并将其粘贴到输出文件txt使用堆栈的算术计算器(错误)

实际计算中,它使用2 stacks;一个持有价值,一个持有经营者。当它扫描一个表达式时,它将值栈中的值和运算符堆栈中的操作符推入。

每次在运算符栈中推送一个优先级高于当前栈顶运算符的运算符时,它将弹出当前运算符,并弹出值栈中的前2个值,执行计算,并将结果推回到值栈中。这会一直运行,直到它在输入txt文件中检测到$

的问题:当我运行该程序,我得到以下异常:“运营商无效”

我不明白这个问题。

Expressions.txt:

3 + 5 

4 + 6 

6 + 7 

$ 

Out.txt(它应该有):

3 + 5 

8 

4 + 6 

10 

6 + 7 

13 

Out.txt始终保持为空。什么是无效操作符?

这里是我的代码:

package firstcalc; 
import java.io.*; 
import java.util.*; 
public class FirstCalc 
{ 
    public interface Stack<E> 
    { 
     int size(); 
     boolean isEmpty(); 
     void push(E e); 
     E top(); 
     E pop(); 
    } 

    public static class ArrayStack<E> implements Stack<E> 
    { 
     public static final int CAPACITY = 100; 
     private E[] data; 
     private int t = -1; 
     public ArrayStack() 
     { 
      this(CAPACITY); 
     } 
     public ArrayStack(int capacity) 
     { 
      data = (E[]) new Object[capacity]; 
     } 

     public int size() 
     { 
      return (t + 1); 
     } 

     public boolean isEmpty() 
     { 
      return (t == -1); 
     } 

     public void push(E e) throws IllegalStateException 
     { 
      if (size() == data.length) throw new IllegalStateException("Stack is full!"); 
      data[++t] = e; 
     } 

     public E top() 
     { 
      if (isEmpty()) return null; 
      return data[t]; 
     } 

     public E pop() 
     { 
      if (isEmpty()) return null; 
      E answer = data[t]; 
      data[t] = null; 
      t--; 
      return answer; 
     } 
} 

static ArrayStack valStk = new ArrayStack<>(); 
static ArrayStack opStk = new ArrayStack<>(); 
static int x; 
static int y; 
static String op; 

public static void doOp() 
{ 
    x = (int) valStk.pop(); 
    y = (int) valStk.pop(); 
    op = (String) opStk.pop(); 
    valStk.push(y); 
    valStk.push(op); 
    valStk.push(x); 
} 

public static void repeatOps (String refOp) 
{ 
    while (valStk.size() > 1 && (prec(refOp) <= prec(opStk.top().toString()))) 
    { 
       doOp(); 
    } 
} 

public static int prec(String op) 
{ 
    switch(op) 
    { 
     case "(": 
     case ")": 
      return 1; 
     case "!": 
      return 2; 
     case "^": 
      return 3; 
     case "*": 
     case "/": 
      return 4; 
     case "+": 
     case "-": 
      return 5; 
     case ">": 
     case ">=": 
     case "<": 
     case "<=": 
      return 6; 
     case "==": 
     case "!=": 
      return 7; 
     case "$": 
      return 8; 
     default: 
      throw new IllegalArgumentException("Invalid Operator!"); 
    } 
} 

public static void main (String[] args) 
{ 
    StringBuilder sb = new StringBuilder(); 
    String str = ""; 
    String line = ""; 
    try 
    { 
       File file = new File("expressions.txt"); 
       Scanner sc = new Scanner(file); 

       FileWriter fw = new FileWriter("out.txt", true); 
       BufferedWriter bw = new BufferedWriter(fw); 
       PrintWriter pw = new PrintWriter(bw); 
       line = sc.nextLine(); 

       while(!line.equals("$")) 
       { 
        pw.println("Expression: " + line); 
        line = line.replaceAll(" ", ""); 

        for(int i = 0; i < line.length(); i++) 
        { 
         char c = line.charAt(i); 
         if(Character.isDigit(c)) 
         { 
          valStk.push(c); 
         } 
         else 
         { 
          if((c == '>' || c == '<' || c == '!' || c == '=') && (line.charAt(i + 1) == '=')) 
          { 
           sb.append(c); 
           sb.append(line.charAt(i + 1)); 
           str = sb.toString(); 
           repeatOps(str); 
          } 
          else 
          { 
           sb.append(c); 
           str = sb.toString(); 
           repeatOps(str); 
          } 
          opStk.push(c); 
         } 
        } 
        pw.println(valStk.top()); 
        line = sc.nextLine(); 
       } 
       pw.close(); 
    } 

    catch(IOException ex) 
    { 
     ex.printStackTrace(); 
    } 
} 
} 
+1

一个简单的办法知道是改变你的异常抛出来'抛出新抛出:IllegalArgumentException(“无效运算符” + OP);' –

回答

1

在下面的代码片段,你继续追加新角色您StringBuilder这将可能发送Strings>=<=>=<=>=等为您的while循环进一步的进展。

if((c == '>' || c == '<' || c == '!' || c == '=') && (line.charAt(i + 1) == '=')) 
{ 
    sb.append(c); 
    sb.append(line.charAt(i + 1)); 
    str = sb.toString(); 
    repeatOps(str); 
} 
else 
{ 
    sb.append(c); 
    str = sb.toString(); 
    repeatOps(str); 
} 

由于这些新创建的Strings在任何情况下都没有定义在switch它去default并打印Exception

你应该做的是每次创建一个新的StringBuilder实例。

例如,

if((c == '>' || c == '<' || c == '!' || c == '=') && (line.charAt(i + 1) == '=')) 
{ 
    sb = new StringBuilder(); 
    sb.append(c); 
    sb.append(line.charAt(i + 1)); 
    repeatOps(sb.toString()); 
} 
else 
{ 
    sb = new StringBuilder(); 
    sb.append(c); 
    repeatOps(sb.toString()); 
}