算法逻辑:
OperandType EvaluateExpression(){
//算术表达式求值的算符优先算法, 设OPTR和OPND分别为运算符栈和运算数栈
//OP为运算符集合
InitStack(OPTR); Push(OPTR, '#');
InitStack(OPND); c = getchar();
while(c != '#' || GetTop(OPTR) != '#'){
if(!In(c, OP)){Push((OPND, c)); c = getchar();}//不是运算符进栈
else
switch(Precede(GetTop(OPTR), c)){
case '<'://栈顶元素优先权低
Push(OPTR, c); c = getchar(); break;
case '='://脱括号并接收下一字符
Pop(OPTR, x); c = getchar();
case '>'://栈顶元素优先权高, 退栈并将结果运算入栈
Pop(OPTR, theta); Pop(OPND, b); Pop(OPND, a);
Push(OPND, Operate(a, theta, b)); break;
}
}
return GetTop(OPND);
}
算法实现:
1. c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXSIZE 100
const char* OPERATOR_SET = "+-*/()#";
typedef struct {
int data[MAXSIZE];
int top;
} OperandStack;
void initOperandStack(OperandStack *s) {
s->top = -1;
}
int pushOperand(OperandStack *s, int elem) {
if (s->top == MAXSIZE - 1) {
fprintf(stderr, "Stack Overflow\n");
return -1;
}
s->data[++s->top] = elem;
return 0;
}
int popOperand(OperandStack *s) {
if (s->top == -1) {
fprintf(stderr, "Stack Underflow\n");
return -1;
}
return s->data[s->top--];
}
typedef struct {
char data[MAXSIZE];
int top;
} OperatorStack;
void initOperatorStack(OperatorStack *s) {
s->top = -1;
}
int pushOperator(OperatorStack *s, char elem) {
if (s->top == MAXSIZE - 1) {
fprintf(stderr, "Stack Overflow\n");
return -1;
}
s->data[++s->top] = elem;
return 0;
}
int popOperator(OperatorStack *s) {
if (s->top == -1) {
fprintf(stderr, "Stack Underflow\n");
return -1;
}
return s->data[s->top--];
}
char peekOperator(OperatorStack *s) {
if (s->top == -1) {
fprintf(stderr, "Stack Underflow\n");
return -1; // Use an invalid character to indicate error
}
return s->data[s->top];
}
int isInOperatorSet(char c) {
return strchr(OPERATOR_SET, c) != NULL;
}
int precedence(char op1, char op2) {
static const char precedence_table[7][7] = {
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'<', '<', '<', '<', '<', '=', ' '},
{'>', '>', '>', '>', ' ', '>', '>'},
{'<', '<', '<', '<', '<', ' ', '='}
};
const char* ptr1 = strchr(OPERATOR_SET, op1);
const char* ptr2 = strchr(OPERATOR_SET, op2);
if (!ptr1 || !ptr2) {
fprintf(stderr, "Operator not found in OPERATOR_SET\n");
return -1;
}
int i = ptr1 - OPERATOR_SET;
int j = ptr2 - OPERATOR_SET;
return precedence_table[i][j];
}
int operate(int a, char op, int b) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b == 0) {
fprintf(stderr, "Division by zero error\n");
return -1; // Using -1 to indicate an error
}
return a / b;
default:
fprintf(stderr, "Invalid operator\n");
return -1; // Again, using -1 to indicate an error
}
}
int evaluateExpression(const char* expression) {
OperatorStack operators;
OperandStack operands;
initOperatorStack(&operators);
initOperandStack(&operands);
if (pushOperator(&operators, '#') == -1) return -1;
const char *ptr = expression;
char c;
while ((c = *ptr++) != '#') {
if (!isInOperatorSet(c) && !isdigit(c) && c != ' ') {
fprintf(stderr, "Invalid character in expression\n");
return -1;
}
if (isdigit(c)) {
int num = c - '0'; // Convert char to integer
while (isdigit(*ptr)) {
num = num * 10 + (*ptr - '0');
ptr++;
}
if (pushOperand(&operands, num) == -1) return -1;
} else if (isInOperatorSet(c)) {
while (!operators.top == -1 && precedence(peekOperator(&operators), c) != '<') {
if (precedence(peekOperator(&operators), c) == '>') {
char op = popOperator(&operators);
int b = popOperand(&operands);
int a = popOperand(&operands);
int result = operate(a, op, b);
if (result == -1 || pushOperand(&operands, result) == -1) return -1;
} else if (precedence(peekOperator(&operators), c) == '=') {
popOperator(&operators);
break;
}
}
if (precedence(peekOperator(&operators), c) == '<') {
if (pushOperator(&operators, c) == -1) return -1;
}
}
}
return popOperand(&operands);
}
int main() {
char expression[1024];
printf("Enter an expression terminated by #:\n");
fgets(expression, sizeof(expression), stdin);
int result = evaluateExpression(expression);
if (result != -1) {
printf("Result: %d\n", result);
} else {
fprintf(stderr, "Failed to evaluate expression.\n");
}
return 0;
}
2. c++
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>
#include <stdexcept>
#include <cstring>
#define MAXSIZE 100
const char* OPERATOR_SET = "+-*/()#";
class OperandStack {
private:
int data[MAXSIZE];
int top;
public:
OperandStack() : top(-1) {}
void push(int elem) {
if (top == MAXSIZE - 1)
throw std::overflow_error("Stack Overflow");
data[++top] = elem;
}
int pop() {
if (top == -1)
throw std::underflow_error("Stack Underflow");
return data[top--];
}
int peek() const {
if (top == -1)
throw std::underflow_error("Stack Underflow");
return data[top];
}
bool isEmpty() const {
return top == -1;
}
};
class OperatorStack {
private:
char data[MAXSIZE];
int top;
public:
OperatorStack() : top(-1) {}
void push(char elem) {
if (top == MAXSIZE - 1)
throw std::overflow_error("Stack Overflow");
data[++top] = elem;
}
char pop() {
if (top == -1)
throw std::underflow_error("Stack Underflow");
return data[top--];
}
char peek() const {
if (top == -1)
throw std::underflow_error("Stack Underflow");
return data[top];
}
bool isEmpty() const {
return top == -1;
}
};
bool isInOperatorSet(char c) {
return strchr(OPERATOR_SET, c) != nullptr;
}
int precedence(char op1, char op2) {
static const char precedence[7][7] = {
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'<', '<', '<', '<', '<', '=', ' '},
{'>', '>', '>', '>', ' ', '>', '>'},
{'<', '<', '<', '<', '<', ' ', '='}
};
const char* ptr1 = strchr(OPERATOR_SET, op1);
const char* ptr2 = strchr(OPERATOR_SET, op2);
if (!ptr1 || !ptr2)
throw std::invalid_argument("Operator not found in OPERATOR_SET");
int i = ptr1 - OPERATOR_SET;
int j = ptr2 - OPERATOR_SET;
return precedence[i][j];
}
int operate(int a, char op, int b) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b == 0)
throw std::runtime_error("Division by zero error");
return a / b;
default:
throw std::invalid_argument("Invalid operator");
}
}
int evaluateExpression(const std::string& expression) {
std::istringstream exprStream(expression);
OperatorStack operators;
OperandStack operands;
operators.push('#');
char c;
while (exprStream >> c, c != '#') {
if (!isInOperatorSet(c) && !isdigit(c) && c != ' ') {
throw std::runtime_error("Invalid character in expression");
}
if (isdigit(c)) {
exprStream.putback(c);
int num;
exprStream >> num;
operands.push(num);
}
else if (isInOperatorSet(c)) {
while (!operators.isEmpty() && precedence(operators.peek(), c) != '<') {
if (precedence(operators.peek(), c) == '>') {
char op = operators.pop();
int b = operands.pop();
int a = operands.pop();
operands.push(operate(a, op, b));
}
else if (precedence(operators.peek(), c) == '=') {
operators.pop();
break;
}
}
if (precedence(operators.peek(), c) == '<') {
operators.push(c);
}
}
}
return operands.pop();
}
int main() {
try {
std::cout << "Enter an expression terminated by #:\n";
std::string expression;
std::getline(std::cin, expression); // Read the whole line of input
int result = evaluateExpression(expression);
std::cout << "Result: " << result << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
3. python
class OperandStack:
def __init__(self):
self.data = []
def push(self, elem):
self.data.append(elem)
def pop(self):
if not self.data:
raise IndexError("Stack Underflow")
return self.data.pop()
def peek(self):
if not self.data:
raise IndexError("Stack Underflow")
return self.data[-1]
def is_empty(self):
return len(self.data) == 0
class OperatorStack:
def __init__(self):
self.data = []
def push(self, elem):
self.data.append(elem)
def pop(self):
if not self.data:
raise IndexError("Stack Underflow")
return self.data.pop()
def peek(self):
if not self.data:
raise IndexError("Stack Underflow")
return self.data[-1]
def is_empty(self):
return len(self.data) == 0
OPERATOR_SET = "+-*/()#"
PRECEDENCE = {
('+', '+'): '>', ('+', '-'): '>', ('+', '*'): '<', ('+', '/'): '<', ('+', '('): '<', ('+', ')'): '>', ('+', '#'): '>',
('-', '+'): '>', ('-', '-'): '>', ('-', '*'): '<', ('-', '/'): '<', ('-', '('): '<', ('-', ')'): '>', ('-', '#'): '>',
('*', '+'): '>', ('*', '-'): '>', ('*', '*'): '>', ('*', '/'): '>', ('*', '('): '<', ('*', ')'): '>', ('*', '#'): '>',
('/', '+'): '>', ('/', '-'): '>', ('/', '*'): '>', ('/', '/'): '>', ('/', '('): '<', ('/', ')'): '>', ('/', '#'): '>',
('(', '+'): '<', ('(', '-'): '<', ('(', '*'): '<', ('(', '/'): '<', ('(', '('): '<', ('(', ')'): '=', ('(', '#'): ' ',
(')', '+'): '>', (')', '-'): '>', (')', '*'): '>', (')', '/'): '>', (')', '('): ' ', (')', ')'): '>', (')', '#'): '>',
('#', '+'): '<', ('#', '-'): '<', ('#', '*'): '<', ('#', '/'): '<', ('#', '('): '<', ('#', ')'): ' ', ('#', '#'): '='
}
def operate(a, op, b):
if op == '+':
return a + b
elif op == '-':
return a - b
elif op == '*':
return a * b
elif op == '/':
if b == 0:
raise ZeroDivisionError("Division by zero")
return a / b
else:
raise ValueError("Invalid operator")
def evaluate_expression(expression):
operators = OperatorStack()
operands = OperandStack()
operators.push('#')
i = 0
while i < len(expression):
if expression[i].isdigit():
num = 0
while i < len(expression) and expression[i].isdigit():
num = num * 10 + int(expression[i])
i += 1
operands.push(num)
continue
elif expression[i] in OPERATOR_SET:
while not operators.is_empty() and PRECEDENCE[(operators.peek(), expression[i])] != '<':
if PRECEDENCE[(operators.peek(), expression[i])] == '>':
op = operators.pop()
b = operands.pop()
a = operands.pop()
operands.push(operate(a, op, b))
elif PRECEDENCE[(operators.peek(), expression[i])] == '=':
operators.pop()
break
if PRECEDENCE[(operators.peek(), expression[i])] == '<':
operators.push(expression[i])
i += 1
return operands.pop()
def main():
expression = input("Enter an expression terminated by #:\n")
expression = expression.strip('#\n') # Remove the trailing '#' and newline for safety
try:
result = evaluate_expression(expression)
print("Result:", result)
except Exception as e:
print("Error:", e)
if __name__ == "__main__":
main()