c语言用顺序栈实现用户输入一个包含“+”、“-”、“*”、“/”、正整数和圆括号的合法数学表达式,计算该表达式的运算结果
时间: 2023-11-05 10:01:21 浏览: 85
c语言算术表达式,加减乘除、乘方、括号。依次输出在求值过程中运算数栈内的栈顶数据变化过程,并最终输出表达式的值
5星 · 资源好评率100%
好的,我知道了。针对您的问题,我可以给出以下C语言代码实现:
```
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MaxSize 50 // 定义栈的最大存储容量
typedef struct {
int top; // 栈顶指针
double data[MaxSize]; // 存储数据的数组
} Stack;
void InitStack(Stack *s) { // 初始化栈
s->top = -1;
}
int StackIsEmpty(Stack *s) { // 判断栈是否为空
return s->top == -1;
}
int StackIsFull(Stack *s) { // 判断栈是否已满
return s->top == MaxSize - 1;
}
void Push(Stack *s, double x) { // 入栈操作
if (StackIsFull(s)) {
printf("栈已满,无法入栈\n");
exit(1); // 终止程序执行
}
s->data[++(s->top)] = x;
}
double Pop(Stack *s) { // 出栈操作
if (StackIsEmpty(s)) {
printf("栈为空,无法出栈\n");
exit(1); // 终止程序执行
}
return s->data[(s->top)--];
}
double GetTop(Stack *s) { // 返回栈顶元素
if (StackIsEmpty(s)) {
printf("栈为空,无法返回栈顶元素\n");
exit(1); // 终止程序执行
}
return s->data[s->top];
}
int GetOperatorPriority(char c) { // 获取运算符优先级
switch (c) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
case ')':
return 0;
default:
printf("非法字符:%c\n", c);
exit(1); // 终止程序执行
}
}
double Calculate(double a, char op, double b) { // 计算两个数之间的运算结果
double result;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
if (b == 0) {
printf("除数为0,出现错误\n");
exit(1); // 终止程序执行
}
result = a / b;
break;
}
return result;
}
double EvaluateExpression(char *expr) { // 计算表达式的值
int i;
double a, b;
char c, op;
Stack numStack, opStack; // numStack:存放操作数的栈,opStack:存放运算符的栈
InitStack(&numStack);
InitStack(&opStack);
i = 0;
while (expr[i] != '\0') {
c = expr[i];
if (isspace(c)) { // 忽略空格
i++;
continue;
} else if (isdigit(c)) { // 遇到数字字符,读取整数或实数
char temp[MaxSize];
int j = 0;
temp[j++] = c;
while (isdigit(expr[++i])) {
temp[j++] = expr[i];
}
if (c == '.') {
temp[j++] = '.';
while (isdigit(expr[++i])) {
temp[j++] = expr[i];
}
}
temp[j] = '\0';
Push(&numStack, atof(temp)); // 将数压入数栈
} else if (c == '(') { // 遇到左括号,将其入栈
Push(&opStack, c);
i++;
} else if (c == ')') { // 遇到右括号,执行括号内的计算
while (GetTop(&opStack) != '(') {
op = Pop(&opStack);
b = Pop(&numStack);
a = Pop(&numStack);
Push(&numStack, Calculate(a, op, b)); // 计算括号内两个数的值
}
Pop(&opStack); // 左括号出栈
i++;
} else { // 遇到运算符,将其入栈前先与栈顶运算符比较优先级
while (!StackIsEmpty(&opStack) && GetOperatorPriority(c) <= GetOperatorPriority(GetTop(&opStack))) {
op = Pop(&opStack);
b = Pop(&numStack);
a = Pop(&numStack);
Push(&numStack, Calculate(a, op, b)); // 计算两个数之间的值
}
Push(&opStack, c);
i++;
}
}
while (!StackIsEmpty(&opStack)) { // 若运算符栈不为空,则继续计算
op = Pop(&opStack);
b = Pop(&numStack);
a = Pop(&numStack);
Push(&numStack, Calculate(a, op, b));
}
return Pop(&numStack); // 将最终结果返回
}
int main() {
char expr[MaxSize];
printf("请输入合法数学表达式:\n");
scanf("%s", expr);
double result = EvaluateExpression(expr);
printf("计算结果为:%.2f\n", result);
return 0;
}
```
这个程序通过顺序栈来实现计算器功能,输入表达式通过遍历表达式字符串实现,用两个栈分别存放数和运算符,如果当前遍历到的是数字,则将其转换成double类型后压入数栈;如果是左括号,则将其压入运算符栈;如果是右括号,则依次取出运算符栈的栈顶元素进行计算,直到遇到左括号;如果是加减乘除运算符,则依次与运算符栈的栈顶元素比较优先级,如果当前运算符的优先级小于等于栈顶运算符的优先级,则取出栈顶运算符和数栈顶部的两个数进行计算;最终将数栈的栈顶元素作为表达式的计算结果输出。
阅读全文