使用堆栈的算术计算器(错误)

时间:2016-02-16 19:03:37

标签: java

我正在尝试使用ArrayStack制作算术计算器。它的工作方式是,它需要一个包含大量表达式的txt文件,并扫描每一行。对于它扫描的每一行,它会复制表达式及其结果,并将它们粘贴到输出txt文件中。

对于实际计算,它使用2 stacks;一个用于保存值,一个用于保存运算符。当它扫描表达式时,它会推送值堆栈中的值以及运算符堆栈中的运算符。

每次在操作堆栈中推送一个优先级高于堆栈当前顶部操作符的op时,它将弹出当前操作,并弹出值堆栈中的前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 个答案:

答案 0 :(得分:1)

在以下代码段中,您不断向StringBuilder添加新字符,这些字符可能会Strings >=<= >=<=>=whileif((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 1}}循环进一步发展。

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()); }

您应该做的是每次都创建一个新的class User { String username; String password; equals(Object other){ return other.username.equals(this.username) && other.password.equals(this.password); } hashCode() { //hash the two values together return (username+password).hashCode(); } 实例。

例如,

    checkIfUserValid(String user, String password){
          u = new User(user, password);
          return set.contains(u);
    }