请使用C语言栈实现可含括号的算术表达式(加、减、乘、除)的求值
时间: 2023-05-25 16:05:14 浏览: 105
以下是使用C语言栈实现含括号的四则运算表达式求值的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
typedef struct {
float data[MAX_SIZE];
int top;
} Stack;
void init(Stack *s) {
s->top = -1;
}
int isEmpty(Stack *s) {
return s->top == -1;
}
void push(Stack *s, float num) {
if (s->top == MAX_SIZE - 1) {
printf("Stack overflow\n");
exit(1);
}
s->top++;
s->data[s->top] = num;
}
float pop(Stack *s) {
if (isEmpty(s)) {
printf("Stack underflow\n");
exit(1);
}
float num = s->data[s->top];
s->top--;
return num;
}
float peek(Stack *s) {
if (isEmpty(s)) {
printf("Stack underflow\n");
exit(1);
}
return s->data[s->top];
}
int isDigit(char ch) {
return ch >= '0' && ch <= '9';
}
float evaluate(char *expr) {
Stack operandStack, operatorStack;
init(&operandStack);
init(&operatorStack);
for (int i = 0; i < strlen(expr); i++) {
if (expr[i] == '(') {
push(&operatorStack, expr[i]);
} else if (isDigit(expr[i])) {
float num = 0;
while (isDigit(expr[i])) {
num = num*10 + (float)(expr[i] - '0');
i++;
}
push(&operandStack, num);
i--;
} else if (expr[i] == '+' || expr[i] == '-' ||
expr[i] == '*' || expr[i] == '/') {
while (!isEmpty(&operatorStack) &&
peek(&operatorStack) != '(' &&
((expr[i] == '*' || expr[i] == '/') ||
(expr[i] == '+' || expr[i] == '-') &&
(peek(&operatorStack) == '*' || peek(&operatorStack) == '/'))) {
char op = (char)pop(&operatorStack);
float op2 = pop(&operandStack);
float op1 = pop(&operandStack);
switch (op) {
case '+': push(&operandStack, op1 + op2); break;
case '-': push(&operandStack, op1 - op2); break;
case '*': push(&operandStack, op1 * op2); break;
case '/': push(&operandStack, op1 / op2); break;
}
}
push(&operatorStack, expr[i]);
} else if (expr[i] == ')') {
while (!isEmpty(&operatorStack) && peek(&operatorStack) != '(') {
char op = (char)pop(&operatorStack);
float op2 = pop(&operandStack);
float op1 = pop(&operandStack);
switch (op) {
case '+': push(&operandStack, op1 + op2); break;
case '-': push(&operandStack, op1 - op2); break;
case '*': push(&operandStack, op1 * op2); break;
case '/': push(&operandStack, op1 / op2); break;
}
}
if (!isEmpty(&operatorStack) && peek(&operatorStack) == '(') {
pop(&operatorStack);
}
}
}
while (!isEmpty(&operatorStack)) {
char op = (char)pop(&operatorStack);
float op2 = pop(&operandStack);
float op1 = pop(&operandStack);
switch (op) {
case '+': push(&operandStack, op1 + op2); break;
case '-': push(&operandStack, op1 - op2); break;
case '*': push(&operandStack, op1 * op2); break;
case '/': push(&operandStack, op1 / op2); break;
}
}
return pop(&operandStack);
}
int main() {
char expr[MAX_SIZE];
printf("Enter an expression: ");
scanf("%s", expr);
float result = evaluate(expr);
printf("Result: %.2f\n", result);
return 0;
}
```
在这个实现中,我们使用了两个栈:一个栈用于存储操作数,另一个栈用于存储操作符。遍历整个表达式,如果遇到数字,则将其压入操作数栈中;如果遇到操作符,则检查操作符栈,将优先级高于当前操作符的栈顶操作符弹出并执行相应的计算操作,直到操作符栈为空或者遇到一个左括号为止,然后将当前操作符压入操作符栈中。如果遇到左括号,则将其压入操作符栈中;如果遇到右括号,则弹出操作符栈中的所有操作符,直到遇到左括号为止,并执行相应的计算操作。当遍历完整个表达式之后,再继续将操作符栈中的操作符弹出并执行相应的计算操作,直到操作符栈为空。
在进行计算操作时,我们需要弹出操作数栈中的两个操作数,然后执行相应的计算操作,并将结果压入操作数栈中。最后,操作数栈中的唯一元素就是表达式的值。
在这个实现中,我们使用了一个辅助函数 `isDigit` 来判断一个字符是否是数字。这个函数比较简单,只需要判断字符的 ASCII 码是否在 '0' 到 '9' 的范围内即可。
阅读全文