【发布时间】:2012-11-05 11:07:50
【问题描述】:
我想知道是否有一种方法可以使用 2 个堆栈一次性解决中缀表达式? 堆栈可以一个用于运算符,另一个用于操作数...
分流码算法求解的标准方法是将中缀表达式转换为后缀(反向抛光)然后求解。我不想先将表达式转换为后缀。
如果表达式是2*3-(6+5)+8,如何解决?
【问题讨论】:
标签: infix-notation stack
我想知道是否有一种方法可以使用 2 个堆栈一次性解决中缀表达式? 堆栈可以一个用于运算符,另一个用于操作数...
分流码算法求解的标准方法是将中缀表达式转换为后缀(反向抛光)然后求解。我不想先将表达式转换为后缀。
如果表达式是2*3-(6+5)+8,如何解决?
【问题讨论】:
标签: infix-notation stack
很晚了,但这是答案。
取两叠:
operator stack { 用于运算符和括号}。operand stack.如果存在要读取的字符:
operand,请按operand stack,如果字符是(,请按operator stack。operator
operator stack 的顶部的优先级不低于此字符。operator stack 弹出operator。operand stack 弹出两个operands(op1 和op2)。op1 op op2 存储在operand stack 返回到2.1。),则与2.2 - 2.4 相同,直到遇到(。Else(没有更多的字符可供阅读):
operator stack 不为空。operand stack 上弹出顶部 2 operands 和 push op1 op op2。从operand stack返回最高值。
【讨论】:
the link中给出的方法确实不错。
让我引用出处:
We will use two stacks:
Operand stack: to keep values (numbers) and
Operator stack: to keep operators (+, -, *, . and ^).
In the following, “process” means, (i) pop operand stack once (value1) (ii) pop operator stack once (operator) (iii) pop operand stack again (value2) (iv) compute value1 operator value2 (v) push the value obtained in operand stack.
Algorithm:
Until the end of the expression is reached, get one character and perform only one of the steps (a) through (f):
(a) If the character is an operand, push it onto the operand stack.
(b) If the character is an operator, and the operator stack is empty then push it onto the operator stack.
(c) If the character is an operator and the operator stack is not empty, and the character's precedence is greater than the precedence of the stack top of operator stack, then push the character onto the operator stack.
(d) If the character is "(", then push it onto operator stack.
(e) If the character is ")", then "process" as explained above until the corresponding "(" is encountered in operator stack. At this stage POP the operator stack and ignore "(."
(f) If cases (a), (b), (c), (d) and (e) do not apply, then process as explained above.
When there are no more input characters, keep processing until the operator stack becomes empty. The values left in the operand stack is the final result of the expression.
我希望这会有所帮助!
【讨论】:
【讨论】:
下面是我在 java 中的中缀表达式求值的尝试。如果您发现任何错误,请告诉我:)
import java.util.*;
public class ArithmeticExpressionEvaluation {
public static void main(String[] args) {
Scanner readExpression = new Scanner(System.in);
System.out.print("Enter the expression: ");
String expression = readExpression.nextLine();
System.out.println(expression);
System.out.println("Result: " + calculateExpression(expression));
}
public static long calculateExpression(String expression) {
Stack<Long> operandStack = new Stack<>();
Stack<Character> operatorStack = new Stack<>();
if (!isValidExpression(expression)) {
System.out.println("Not a valid expression to evaluate");
return 0;
}
int i = 0;
String currentInteger = null;
while (i < expression.length()) {
// System.out.println(expression.charAt(i));
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
currentInteger = expression.charAt(i) + "";
i++;
while (i != expression.length() && (expression.charAt(i) >= '0' && expression.charAt(i) <= '9')) {
currentInteger = currentInteger + expression.charAt(i);
i++;
}
operandStack.push(Long.parseLong(currentInteger));
} else {
if (expression.charAt(i) == ')') {
while (operatorStack.peek() != '(') {
performArithmeticOperation(operandStack, operatorStack);
}
operatorStack.pop();
} else {
Character currentOperator = expression.charAt(i);
Character lastOperator = (operatorStack.isEmpty() ? null : operatorStack.peek());
if (lastOperator != null && checkPrecedence(currentOperator, lastOperator)) {
performArithmeticOperation(operandStack, operatorStack);
}
operatorStack.push(expression.charAt(i));
}
i++;
}
}
while (!operatorStack.isEmpty()) {
performArithmeticOperation(operandStack, operatorStack);
}
// System.out.println(Arrays.toString(operandStack.toArray()));
// System.out.println(Arrays.toString(operatorStack.toArray()));
return operandStack.pop();
}
public static void performArithmeticOperation(Stack<Long> operandStack, Stack<Character> operatorStack) {
try {
long value1 = operandStack.pop();
long value2 = operandStack.pop();
char operator = operatorStack.pop();
long intermediateResult = arithmeticOperation(value1, value2, operator);
operandStack.push(intermediateResult);
} catch (EmptyStackException e) {
System.out.println("Not a valid expression to evaluate");
throw e;
}
}
public static boolean checkPrecedence(Character operator1, Character operator2) {
List<Character> precedenceList = new ArrayList<>();
precedenceList.add('(');
precedenceList.add(')');
precedenceList.add('/');
precedenceList.add('*');
precedenceList.add('%');
precedenceList.add('+');
precedenceList.add('-');
if(operator2 == '(' ){
return false;
}
if (precedenceList.indexOf(operator1) > precedenceList.indexOf(operator2)) {
return true;
} else {
return false;
}
}
public static long arithmeticOperation(long value2, long value1, Character operator) {
long result;
switch (operator) {
case '+':
result = value1 + value2;
break;
case '-':
result = value1 - value2;
break;
case '*':
result = value1 * value2;
break;
case '/':
result = value1 / value2;
break;
case '%':
result = value1 % value2;
break;
default:
result = value1 + value2;
}
return result;
}
public static boolean isValidExpression(String expression) {
if ((!Character.isDigit(expression.charAt(0)) && !(expression.charAt(0) == '('))
|| (!Character.isDigit(expression.charAt(expression.length() - 1)) && !(expression.charAt(expression.length() - 1) == ')'))) {
return false;
}
HashSet<Character> validCharactersSet = new HashSet<>();
validCharactersSet.add('*');
validCharactersSet.add('+');
validCharactersSet.add('-');
validCharactersSet.add('/');
validCharactersSet.add('%');
validCharactersSet.add('(');
validCharactersSet.add(')');
Stack<Character> validParenthesisCheck = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
if (!Character.isDigit(expression.charAt(i)) && !validCharactersSet.contains(expression.charAt(i))) {
return false;
}
if (expression.charAt(i) == '(') {
validParenthesisCheck.push(expression.charAt(i));
}
if (expression.charAt(i) == ')') {
if (validParenthesisCheck.isEmpty()) {
return false;
}
validParenthesisCheck.pop();
}
}
if (validParenthesisCheck.isEmpty()) {
return true;
} else {
return false;
}
}
}
【讨论】: