#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 100
// 字符栈:存储 运算符/括号
typedef struct {
char data[MAXSIZE];
int top;
} CharStack;
// 数值栈:存储 浮点数
typedef struct {
double data[MAXSIZE]; // 改为 double
int top;
} NumStack;
// ======================== 字符栈操作 ========================
void InitCharStack(CharStack *s) {
s->top = -1;
memset(s->data, 0, sizeof(s->data));
}
int IsCharEmpty(CharStack *s) {
return s->top == -1;
}
int PushChar(CharStack *s, char ch) {
if (s->top == MAXSIZE - 1) return 0;
s->data[++s->top] = ch;
return 1;
}
int PopChar(CharStack *s, char *ch) {
if (IsCharEmpty(s)) return 0;
*ch = s->data[s->top--];
return 1;
}
char GetTopChar(CharStack *s) {
if (IsCharEmpty(s)) return '#';
return s->data[s->top];
}
// ======================== 数值栈操作(浮点版) ========================
void InitNumStack(NumStack *s) {
s->top = -1;
memset(s->data, 0, sizeof(s->data));
}
int PushNum(NumStack *s, double num) { // double
if (s->top == MAXSIZE - 1) return 0;
s->data[++s->top] = num;
return 1;
}
int PopNum(NumStack *s, double *num) { // double
if (s->top == -1) return 0;
*num = s->data[s->top--];
return 1;
}
double GetTopNum(NumStack *s) { // double
if (s->top == -1) return 0;
return s->data[s->top];
}
// ======================== 工具函数 ========================
int IsOperator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
int IsNumber(char ch) {
return (ch >= '0' && ch <= '9') || ch == '.'; // 支持小数点
}
int GetPriority(char ch) {
if (ch == '*' || ch == '/') return 2;
if (ch == '+' || ch == '-') return 1;
return 0;
}
// 浮点运算
double Operate(double a, double b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b == 0) {
printf("错误:除数不能为0!\n");
exit(1);
}
return a / b;
default: return 0;
}
}
// ======================== 中缀转后缀 ========================
void InfixToPostfix(const char *infix, char *postfix) {
CharStack s;
InitCharStack(&s);
int i = 0, j = 0;
char ch, topOp;
memset(postfix, 0, MAXSIZE);
while (infix[i] != '\0' && i < MAXSIZE - 1) {
ch = infix[i];
if (IsNumber(ch)) {
while (IsNumber(infix[i])) {
postfix[j++] = infix[i++];
}
postfix[j++] = ' ';
} else if (ch == '(') {
PushChar(&s, ch);
i++;
} else if (ch == ')') {
while (!IsCharEmpty(&s) && GetTopChar(&s) != '(') {
PopChar(&s, &topOp);
postfix[j++] = topOp;
postfix[j++] = ' ';
}
PopChar(&s, &topOp);
i++;
} else if (IsOperator(ch)) {
while (!IsCharEmpty(&s) && GetPriority(GetTopChar(&s)) >= GetPriority(ch)) {
PopChar(&s, &topOp);
postfix[j++] = topOp;
postfix[j++] = ' ';
}
PushChar(&s, ch);
i++;
} else {
i++;
}
}
while (!IsCharEmpty(&s)) {
PopChar(&s, &topOp);
postfix[j++] = topOp;
postfix[j++] = ' ';
}
postfix[j] = '\0';
}
// ======================== 后缀表达式求值 ========================
double CalculatePostfix(const char *postfix) {
NumStack s;
InitNumStack(&s);
int i = 0;
char ch;
double a, b;
while (postfix[i] != '\0' && i < MAXSIZE - 1) {
ch = postfix[i];
if (IsNumber(ch)) {
double num = 0;
int dot = 0;
double div = 10;
while (IsNumber(postfix[i])) {
if (postfix[i] == '.') {
dot = 1;
} else {
if (!dot) {
num = num * 10 + (postfix[i] - '0');
} else {
num = num + (postfix[i] - '0') / div;
div *= 10;
}
}
i++;
}
PushNum(&s, num);
} else if (IsOperator(ch)) {
PopNum(&s, &b);
PopNum(&s, &a);
PushNum(&s, Operate(a, b, ch));
i++;
} else {
i++;
}
}
return GetTopNum(&s);
}
// ======================== 菜单 ========================
void Menu() {
printf("==================== 四则运算表达式求值 ====================\n");
printf(" 1. 计算表达式结果\n");
printf(" 0. 退出程序\n");
printf("==================================================================\n");
printf("请输入功能编号:");
}
// ======================== 主函数 ========================
int main() {
int choice;
char infix[MAXSIZE] = {0};
char postfix[MAXSIZE] = {0};
while (1) {
Menu();
if (scanf("%d", &choice) != 1) {
printf("输入错误!\n\n");
while (getchar() != '\n');
continue;
}
getchar();
switch (choice) {
case 1:
printf("\n请输入算术表达式(支持小数 + - * / ( ),如:(3.5+2.5)*2-6/2.5):\n");
fgets(infix, MAXSIZE, stdin);
infix[strcspn(infix, "\n")] = '\0';
InfixToPostfix(infix, postfix);
printf("后缀表达式:%s\n", postfix);
double res = CalculatePostfix(postfix);
printf("计算结果:%.2f\n\n", res); // 保留两位小数
break;
case 0:
printf("程序已退出!\n");
return 0;
default:
printf("输入错误,请重新选择!\n\n");
}
}
}