使用C语言:1.表达式求值问题,应用“栈”编写一个计算器,要求: a)支持整数(长整型范围内)四则混合运算; b)输入应是中缀表达式,对不合法的输入应有提示; c)能够输出正确计算结果; d)示例如输入5(10-3)/7,输出结果
时间: 2024-02-11 09:03:38 浏览: 84
好的,这是一个经典的表达式求值问题。我会用C语言来编写一个基于栈的计算器来解决这个问题。
首先,我们需要定义一个栈的结构体,用来存储表达式中的操作符和数字。
```c
typedef struct {
int top; // 栈顶指针
int data[MAXSIZE]; // 栈中存储的数据
} Stack;
```
接下来,我们需要定义一些栈的基本操作,如入栈、出栈、获取栈顶元素等。
```c
// 初始化栈
void init(Stack *s) {
s->top = -1;
}
// 判断栈是否为空
int is_empty(Stack *s) {
return s->top == -1;
}
// 判断栈是否已满
int is_full(Stack *s) {
return s->top == MAXSIZE - 1;
}
// 入栈
void push(Stack *s, int x) {
if (is_full(s)) {
printf("Error: stack overflow\n");
exit(1);
}
s->data[++s->top] = x;
}
// 出栈
int pop(Stack *s) {
if (is_empty(s)) {
printf("Error: stack underflow\n");
exit(1);
}
return s->data[s->top--];
}
// 获取栈顶元素
int peek(Stack *s) {
if (is_empty(s)) {
printf("Error: stack underflow\n");
exit(1);
}
return s->data[s->top];
}
```
现在,我们可以开始编写计算器的主函数了。首先,我们需要从用户输入中缀表达式,然后使用栈来处理表达式。
```c
int main() {
char expr[MAXSIZE]; // 存储用户输入的中缀表达式
printf("请输入中缀表达式:");
scanf("%s", expr);
Stack op_stack; // 用于存储操作符的栈
Stack num_stack; // 用于存储数字的栈
init(&op_stack);
init(&num_stack);
// 遍历中缀表达式
for (int i = 0; expr[i] != '\0'; i++) {
if (isdigit(expr[i])) {
// 如果是数字,直接入数字栈
int num = 0;
while (isdigit(expr[i])) {
num = num * 10 + (expr[i] - '0');
i++;
}
push(&num_stack, num);
i--;
} else if (expr[i] == '(') {
// 如果是左括号,直接入操作符栈
push(&op_stack, '(');
} else if (expr[i] == ')') {
// 如果是右括号,将操作符栈中的操作符弹出直到遇到左括号,并将计算结果入数字栈
while (peek(&op_stack) != '(') {
int b = pop(&num_stack);
int a = pop(&num_stack);
int op = pop(&op_stack);
push(&num_stack, compute(op, a, b));
}
pop(&op_stack); // 弹出左括号
} else if (is_operator(expr[i])) {
// 如果是操作符,将其与操作符栈顶元素比较优先级
while (!is_empty(&op_stack) && priority(peek(&op_stack)) >= priority(expr[i])) {
int b = pop(&num_stack);
int a = pop(&num_stack);
int op = pop(&op_stack);
push(&num_stack, compute(op, a, b));
}
push(&op_stack, expr[i]);
} else {
// 如果是非法字符,提示错误并退出程序
printf("Error: invalid input\n");
exit(1);
}
}
// 处理完表达式后,将操作符栈中的所有操作符弹出并计算结果
while (!is_empty(&op_stack)) {
int b = pop(&num_stack);
int a = pop(&num_stack);
int op = pop(&op_stack);
push(&num_stack, compute(op, a, b));
}
// 打印计算结果
printf("计算结果:%d\n", pop(&num_stack));
return 0;
}
```
其中,`is_operator`函数用于判断一个字符是否为操作符,`priority`函数用于比较两个操作符的优先级,`compute`函数用于计算两个数字的运算结果。
```c
// 判断一个字符是否为操作符
int is_operator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 比较两个操作符的优先级
int priority(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
// 计算两个数字的运算结果
int compute(char op, int a, int b) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
default:
return 0;
}
}
```
现在,我们可以编译并运行这个程序,输入一个中缀表达式,就可以得到正确的计算结果了。例如,输入`5*(10-3)/7`,程序会输出`计算结果:2`。
阅读全文