java 中的 bc 实用程序在某些情况下失败
bc utility in java, fails for some cases
我正在尝试在 java 中编写简单的 bc 实用程序。我的程序在大多数情况下都运行良好,但对于表达式 4+4*3-3-2-1/3 却失败了。基本上是连续的 - 运营商。不确定我是否涵盖了所有边缘情况。任何让它变得更好的建议都会非常有帮助。谢谢
//ENUM for operations allowed.
private enum Operators {
ADD (1, "+"),
SUBTRACT (1, "-"),
MULTIPLY (2, "*"),
DIVIDE (2, "/");
String operator;
// Operator priority
int weight;
Operators(int w, String o) {
this.operator = o;
this.weight = w;
}
public String getOperator() {
return operator;
}
public int getWeight() {
return weight;
}
}
// Stack and Queue to convert expression to postfix
LinkedList<String> resultQueue = new LinkedList<String>();
Stack<Operators> operatorStack = new Stack<Operators>();
//Stack to evaluate postfix expression
Stack<Integer> evalStack = new Stack<Integer>();
public int eval(String exp) {
char[] expChar = exp.toCharArray();
int i = 0;
StringBuilder sb = new StringBuilder();
while (i < expChar.length){
if (expChar[i] >= '0' && expChar[i] <= '9') {
sb.append(expChar[i]);
if (i == expChar.length - 1) {
resultQueue.add(sb.toString());
while (!operatorStack.isEmpty()){
resultQueue.add(operatorStack.pop().getOperator());
}
}
} else if (expChar[i] == '+' || expChar[i] == '-' || expChar[i] == '/' || expChar[i] == '*'){
if (sb.length() > 0) {
resultQueue.add(sb.toString());
sb = new StringBuilder();
}
pushOperator(expChar[i]);
} else
return 0;
i++;
}
for (String r : resultQueue){
if (r.charAt(0) > '0' && r.charAt(0) < '9'){
evalStack.push(Integer.valueOf(r));
}else {
try {
int op2 = evalStack.pop();
int op1 = evalStack.pop();
if (r.charAt(0) == '+')
evalStack.push(Integer.valueOf(op1+op2));
else if (r.charAt(0) == '-')
evalStack.push(Integer.valueOf(op1-op2));
else if (r.charAt(0) == '/')
evalStack.push(Integer.valueOf(op1/op2));
else if (r.charAt(0) == '*')
evalStack.push(Integer.valueOf(op1*op2));
} catch (Exception e){
System.out.println("Parse Error");
return 0;
}
}
}
int result=0;
try{
result = evalStack.pop();
}catch (Exception e){
System.out.println("Parse Error");
}
return result;
}
private void pushOperator(char c) {
Operators val = getOperator(c);
if (operatorStack.isEmpty() || val.getWeight() >= operatorStack.peek().getWeight()){
operatorStack.push(val);
} else {
while (!operatorStack.isEmpty() && val.getWeight() <= operatorStack.peek().getWeight()){
resultQueue.add(operatorStack.pop().getOperator());
}
operatorStack.push(val);
}
}
private Operators getOperator(char c) {
for (Operators o: Operators.values()){
if (o.getOperator().equals(String.valueOf(c)))
return o;
}
throw new IllegalArgumentException("Operator not supported");
}
public static void main(String[] args) {
BC bc = new BC();
System.out.println("Please enter expression: ");
Scanner scn = new Scanner(System.in);
String exp = scn.nextLine();
//remove white spaces
exp = exp.replaceAll(" ", "");
System.out.println("Result: " + bc.eval(exp));
scn.close();
}
问题在于,对于连续的减法运算,您计算的方向错误。您从右到左计算,而您需要从左到右计算。
如果你在堆栈上有操作数 12 3 2 0 - - -
你计算有效
12 - (3 - (2 - 0)) = 11
正确的是
12 - (3 + 2 + 0) = 7
一个可能的解决方案是修复它。在开始计算之前,您需要将堆栈上的操作数更改为 12 3 2 0 + + -
.
查看这个可以在计算循环之前执行的片段。
// your code
...
}
i++;
}
for (i = 0; i < resultQueue.size() - 1; i++) {
if ("-".equals(resultQueue.get(i)) && "-".equals(resultQueue.get(i+1))) {
resultQueue.set(i, "+");
}
}
// your code
for (String r : resultQueue) {
if (r.charAt(0) > '0' && r.charAt(0) < '9') {
...
我正在尝试在 java 中编写简单的 bc 实用程序。我的程序在大多数情况下都运行良好,但对于表达式 4+4*3-3-2-1/3 却失败了。基本上是连续的 - 运营商。不确定我是否涵盖了所有边缘情况。任何让它变得更好的建议都会非常有帮助。谢谢
//ENUM for operations allowed.
private enum Operators {
ADD (1, "+"),
SUBTRACT (1, "-"),
MULTIPLY (2, "*"),
DIVIDE (2, "/");
String operator;
// Operator priority
int weight;
Operators(int w, String o) {
this.operator = o;
this.weight = w;
}
public String getOperator() {
return operator;
}
public int getWeight() {
return weight;
}
}
// Stack and Queue to convert expression to postfix
LinkedList<String> resultQueue = new LinkedList<String>();
Stack<Operators> operatorStack = new Stack<Operators>();
//Stack to evaluate postfix expression
Stack<Integer> evalStack = new Stack<Integer>();
public int eval(String exp) {
char[] expChar = exp.toCharArray();
int i = 0;
StringBuilder sb = new StringBuilder();
while (i < expChar.length){
if (expChar[i] >= '0' && expChar[i] <= '9') {
sb.append(expChar[i]);
if (i == expChar.length - 1) {
resultQueue.add(sb.toString());
while (!operatorStack.isEmpty()){
resultQueue.add(operatorStack.pop().getOperator());
}
}
} else if (expChar[i] == '+' || expChar[i] == '-' || expChar[i] == '/' || expChar[i] == '*'){
if (sb.length() > 0) {
resultQueue.add(sb.toString());
sb = new StringBuilder();
}
pushOperator(expChar[i]);
} else
return 0;
i++;
}
for (String r : resultQueue){
if (r.charAt(0) > '0' && r.charAt(0) < '9'){
evalStack.push(Integer.valueOf(r));
}else {
try {
int op2 = evalStack.pop();
int op1 = evalStack.pop();
if (r.charAt(0) == '+')
evalStack.push(Integer.valueOf(op1+op2));
else if (r.charAt(0) == '-')
evalStack.push(Integer.valueOf(op1-op2));
else if (r.charAt(0) == '/')
evalStack.push(Integer.valueOf(op1/op2));
else if (r.charAt(0) == '*')
evalStack.push(Integer.valueOf(op1*op2));
} catch (Exception e){
System.out.println("Parse Error");
return 0;
}
}
}
int result=0;
try{
result = evalStack.pop();
}catch (Exception e){
System.out.println("Parse Error");
}
return result;
}
private void pushOperator(char c) {
Operators val = getOperator(c);
if (operatorStack.isEmpty() || val.getWeight() >= operatorStack.peek().getWeight()){
operatorStack.push(val);
} else {
while (!operatorStack.isEmpty() && val.getWeight() <= operatorStack.peek().getWeight()){
resultQueue.add(operatorStack.pop().getOperator());
}
operatorStack.push(val);
}
}
private Operators getOperator(char c) {
for (Operators o: Operators.values()){
if (o.getOperator().equals(String.valueOf(c)))
return o;
}
throw new IllegalArgumentException("Operator not supported");
}
public static void main(String[] args) {
BC bc = new BC();
System.out.println("Please enter expression: ");
Scanner scn = new Scanner(System.in);
String exp = scn.nextLine();
//remove white spaces
exp = exp.replaceAll(" ", "");
System.out.println("Result: " + bc.eval(exp));
scn.close();
}
问题在于,对于连续的减法运算,您计算的方向错误。您从右到左计算,而您需要从左到右计算。
如果你在堆栈上有操作数 12 3 2 0 - - -
你计算有效
12 - (3 - (2 - 0)) = 11
正确的是
12 - (3 + 2 + 0) = 7
一个可能的解决方案是修复它。在开始计算之前,您需要将堆栈上的操作数更改为 12 3 2 0 + + -
.
查看这个可以在计算循环之前执行的片段。
// your code
...
}
i++;
}
for (i = 0; i < resultQueue.size() - 1; i++) {
if ("-".equals(resultQueue.get(i)) && "-".equals(resultQueue.get(i+1))) {
resultQueue.set(i, "+");
}
}
// your code
for (String r : resultQueue) {
if (r.charAt(0) > '0' && r.charAt(0) < '9') {
...