C语言请使用栈实现可含括号的算术表达式(加、减、乘、除)的求值(注意:运算数可为十进制的整数,该整数可为负数)
时间: 2023-06-01 15:02:46 浏览: 178
以下是使用栈实现可含括号的算术表达式的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_STACK_SIZE 100
// 栈结构体定义
typedef struct {
int top;
int data[MAX_STACK_SIZE];
} Stack;
// 初始化栈
void initStack(Stack *s) {
s->top = -1;
}
// 判断栈是否为空
int isEmpty(Stack *s) {
return s->top == -1;
}
// 判断栈是否已满
int isFull(Stack *s) {
return s->top == MAX_STACK_SIZE - 1;
}
// 入栈
void push(Stack *s, int x) {
if (isFull(s)) {
fprintf(stderr, "Stack overflow.\n");
exit(EXIT_FAILURE);
}
s->data[++s->top] = x;
}
// 出栈
int pop(Stack *s) {
if (isEmpty(s)) {
fprintf(stderr, "Stack underflow.\n");
exit(EXIT_FAILURE);
}
return s->data[s->top--];
}
// 取栈顶元素
int peek(Stack *s) {
if (isEmpty(s)) {
fprintf(stderr, "Stack underflow.\n");
exit(EXIT_FAILURE);
}
return s->data[s->top];
}
// 判断操作符优先级
int precedence(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
// 计算表达式
int evaluateExpression(char *exp) {
Stack operandStack;
Stack operatorStack;
initStack(&operandStack);
initStack(&operatorStack);
// 扫描表达式
int i = 0;
while (exp[i] != '\0') {
if (isdigit(exp[i]) || exp[i] == '-') {
// 处理操作数
int num = 0;
int sign = 1;
if (exp[i] == '-') {
sign = -1;
i++;
}
while (isdigit(exp[i])) {
num = num * 10 + (exp[i] - '0');
i++;
}
num *= sign;
push(&operandStack, num);
} else if (exp[i] == '(') {
// 处理左括号
push(&operatorStack, exp[i]);
i++;
} else if (exp[i] == ')') {
// 处理右括号
while (peek(&operatorStack) != '(') {
char op = pop(&operatorStack);
int b = pop(&operandStack);
int a = pop(&operandStack);
int result;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
default:
fprintf(stderr, "Invalid operator.\n");
exit(EXIT_FAILURE);
}
push(&operandStack, result);
}
pop(&operatorStack); // 弹出左括号
i++;
} else if (isspace(exp[i])) {
// 忽略空白字符
i++;
} else {
// 处理操作符
while (!isEmpty(&operatorStack) && peek(&operatorStack) != '(' && precedence(exp[i]) <= precedence(peek(&operatorStack))) {
char op = pop(&operatorStack);
int b = pop(&operandStack);
int a = pop(&operandStack);
int result;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
default:
fprintf(stderr, "Invalid operator.\n");
exit(EXIT_FAILURE);
}
push(&operandStack, result);
}
push(&operatorStack, exp[i]);
i++;
}
}
// 处理剩余的操作符
while (!isEmpty(&operatorStack)) {
char op = pop(&operatorStack);
int b = pop(&operandStack);
int a = pop(&operandStack);
int result;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
default:
fprintf(stderr, "Invalid operator.\n");
exit(EXIT_FAILURE);
}
push(&operandStack, result);
}
// 返回最终结果
return pop(&operandStack);
}
int main() {
char exp[100];
printf("Enter an arithmetic expression: ");
fgets(exp, sizeof(exp), stdin);
int result = evaluateExpression(exp);
printf("Result: %d\n", result);
return 0;
}
```
该程序使用两个栈,一个用于存储操作数,另一个用于存储操作符。程序首先扫描表达式,逐个处理每个字符。如果当前字符是数字或负号,则将其解析为操作数,并入操作数栈。如果当前字符是左括号,则将其入操作符栈。如果当前字符是右括号,则弹出操作符栈中的操作符,直到遇到左括号,将这些操作符与操作数栈中的操作数进行计算,并将计算结果入操作数栈。如果当前字符是空白字符,则忽略它。如果当前字符是操作符,则弹出操作符栈中的操作符,直到遇到左括号或优先级较低的操作符,将这些操作符与操作数栈中的操作数进行计算,并将计算结果入操作数栈。最后,处理完所有字符后,将操作符栈中剩余的操作符与操作数栈中的操作数进行计算,最终结果即为操作数栈中唯一的元素。
阅读全文