我正在尝试使用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();
}
}
}
答案 0 :(得分: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
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);
}