用c语言解决1. 表达式求值问题,应用“栈”编写一个计算器,要求: a) 支持整数(长整型范围内)四则混合运算; b) 输入应是中缀表达式,对不合法的输入应有提示; c) 能够输出正确计算结果; d) 示例 如 输入 5*(10-3) / 7 ,输出结果 5
时间: 2024-01-22 21:20:38 浏览: 22
以下是使用C语言解决表达式求值问题的代码,其中使用了栈数据结构:
```
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_EXPR_LEN 1000
#define MAX_STACK_SIZE 1000
typedef struct stack {
int top;
long long data[MAX_STACK_SIZE];
} Stack;
void push(Stack *s, long long x) {
if (s->top == MAX_STACK_SIZE - 1) {
printf("Stack overflow!\n");
exit(EXIT_FAILURE);
}
s->data[++(s->top)] = x;
}
long long pop(Stack *s) {
if (s->top == -1) {
printf("Stack underflow!\n");
exit(EXIT_FAILURE);
}
return s->data[(s->top)--];
}
long long peek(Stack *s) {
if (s->top == -1) {
printf("Stack underflow!\n");
exit(EXIT_FAILURE);
}
return s->data[s->top];
}
int is_operator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/');
}
int precedence(char c) {
if (c == '*' || c == '/') {
return 2;
} else if (c == '+' || c == '-') {
return 1;
} else {
return 0;
}
}
int is_valid_input(char *expr) {
int len = strlen(expr);
int bracket_count = 0;
for (int i = 0; i < len; i++) {
char c = expr[i];
if (isdigit(c)) {
continue;
} else if (is_operator(c)) {
if (i == 0 || i == len - 1) {
return 0;
} else if (is_operator(expr[i-1]) || is_operator(expr[i+1])) {
return 0;
}
} else if (c == '(') {
bracket_count++;
} else if (c == ')') {
bracket_count--;
if (bracket_count < 0) {
return 0;
}
} else {
return 0;
}
}
return (bracket_count == 0);
}
long long evaluate(char *expr) {
if (!is_valid_input(expr)) {
printf("Invalid input!\n");
exit(EXIT_FAILURE);
}
Stack operand_stack, operator_stack;
operand_stack.top = -1;
operator_stack.top = -1;
int len = strlen(expr);
int i = 0;
while (i < len) {
char c = expr[i];
if (isdigit(c)) {
long long num = 0;
while (i < len && isdigit(expr[i])) {
num = 10 * num + (expr[i] - '0');
i++;
}
push(&operand_stack, num);
} else if (is_operator(c)) {
while (operator_stack.top >= 0 && precedence(peek(&operator_stack)) >= precedence(c)) {
long long op2 = pop(&operand_stack);
long long op1 = pop(&operand_stack);
char op = pop(&operator_stack);
if (op == '+') {
push(&operand_stack, op1 + op2);
} else if (op == '-') {
push(&operand_stack, op1 - op2);
} else if (op == '*') {
push(&operand_stack, op1 * op2);
} else if (op == '/') {
push(&operand_stack, op1 / op2);
}
}
push(&operator_stack, c);
i++;
} else if (c == '(') {
push(&operator_stack, c);
i++;
} else if (c == ')') {
while (peek(&operator_stack) != '(') {
long long op2 = pop(&operand_stack);
long long op1 = pop(&operand_stack);
char op = pop(&operator_stack);
if (op == '+') {
push(&operand_stack, op1 + op2);
} else if (op == '-') {
push(&operand_stack, op1 - op2);
} else if (op == '*') {
push(&operand_stack, op1 * op2);
} else if (op == '/') {
push(&operand_stack, op1 / op2);
}
}
pop(&operator_stack);
i++;
} else {
printf("Invalid input!\n");
exit(EXIT_FAILURE);
}
}
while (operator_stack.top >= 0) {
long long op2 = pop(&operand_stack);
long long op1 = pop(&operand_stack);
char op = pop(&operator_stack);
if (op == '+') {
push(&operand_stack, op1 + op2);
} else if (op == '-') {
push(&operand_stack, op1 - op2);
} else if (op == '*') {
push(&operand_stack, op1 * op2);
} else if (op == '/') {
push(&operand_stack, op1 / op2);
}
}
return pop(&operand_stack);
}
int main() {
char expr[MAX_EXPR_LEN];
printf("Enter an expression: ");
fgets(expr, MAX_EXPR_LEN, stdin);
expr[strlen(expr)-1] = '\0'; // remove the newline character from the input
long long result = evaluate(expr);
printf("Result: %lld\n", result);
return 0;
}
```
这个代码使用两个栈:一个用于存储操作数(operand),一个用于存储运算符(operator)。
首先,程序检查输入是否合法。表达式中只能包含数字、加减乘除运算符和括号,而且括号必须匹配。如果输入不合法,程序会输出错误信息并退出。
然后,程序遍历中缀表达式,根据以下规则进行计算:
- 如果遇到数字,将其作为操作数入栈 operand_stack 中;
- 如果遇到运算符,将其与 operator_stack 栈顶的运算符进行比较。如果栈顶的运算符优先级大于等于当前运算符,就从 operator_stack 中弹出一个运算符,从 operand_stack 中弹出两个操作数,进行计算并将结果入栈 operand_stack 中。重复这个过程直到栈顶的运算符优先级小于当前运算符,然后将当前运算符入栈 operator_stack 中;
- 如果遇到左括号,将其直接入栈 operator_stack 中;
- 如果遇到右括号,将 operator_stack 中的运算符依次弹出,并从 operand_stack 中弹出两个操作数进行计算,直到遇到左括号为止。左括号不入栈 operand_stack 中;
- 如果遇到其他字符,说明输入不合法,程序会输出错误信息并退出。
最后,当中缀表达式遍历结束后,需要将 operator_stack 中的所有运算符依次弹出,从 operand_stack 中弹出两个操作数进行计算,直到 operator_stack 为空。最终 operand_stack 中只剩下一个操作数,就是表达式的计算结果。