算法
先将中缀表达式转为后缀表达式:
【C语言】用顺序栈实现中缀表达式转后缀表达式 算法+全代码实现
再计算后缀表达式:
- 从左到右依次扫描表达式的各元素
- 若是操作数,直接入栈
- 若是运算符,弹出两个栈顶元素进行相应运算,运算结果再入栈(先出栈的操作数在运算符右边)
可以将两部分同时进行,创建运算符栈和操作数栈,边转边计算,运算符出栈时直接在操作数栈进行计算
由于上篇文章写了中缀转后缀,这里就直接计算后缀,两部分分开进行。操作数栈(用来计算后缀表达式的栈)的基本操作跟运算符栈(用来中缀转后缀)是一样的,只需改个数据类型
后缀表达式的操作数只能为0-9整数~
计算后缀表达式代码
typedef struct {
float data[Max];
int top;
}Sqstack_cal;
//初始化栈_calculator
void Initstack_cal(Sqstack_cal* s) {
s->top = -1;
}
//入栈_计算后缀表达式
bool Push_cal(Sqstack_cal* s, float x) {
bool ret = false;
if (s->top != Max - 1) {
s->data[++s->top] = x;
ret = true;
}
return ret;
}
//出栈_calculator
float Pop_cal(Sqstack_cal* s) {
float x = 0;
if (s->top != -1)
x = s->data[s->top--];
return x;
}
//读栈顶元素_calculator
float Top_cal(Sqstack_cal s) {
return s.data[s.top];
}
//char转floaat(0-9)
float charTofloat(char a) {
int ret = 0;
if (a >= '0' && a <= '9')
ret = a - '0';
return (float)ret;
}
//计算后缀表达式(操作数为0-9整数)
float Calculator_end(Sqstack s) {
Sqstack_cal n;
Initstack_cal(&n);
for (int i = 0; i <= s.top; i++) {
if (s.data[i] >= '0' && s.data[i] <= '9') {
Push_cal(&n, charTofloat(s.data[i]));
}
else if (s.data[i] == '+' || s.data[i] == '-' || s.data[i] == '*' || s.data[i] == '/') {
float x = Pop_cal(&n);
switch (s.data[i]) {
case '+':
Push_cal(&n, Pop_cal(&n) + x);
break;
case '-':
Push_cal(&n, Pop_cal(&n) - x);
break;
case '*':
Push_cal(&n, Pop_cal(&n) * x);
break;
case '/':
Push_cal(&n, Pop_cal(&n) / x);
break;
}
}
}
return Top_cal(n);
}
全代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#define Max 100
typedef struct {
char data[Max];
int top;
}Sqstack;
typedef struct {
float data[Max];
int top;
}Sqstack_cal;
//初始化栈
void Initstack(Sqstack* s) {
s->top = -1;
}
//判空 空返回1
bool IsEmpty(Sqstack s) {
int ret = false;
if (s.top == -1)
ret = true;
return ret;
}
//入栈
bool Push(Sqstack* s, char x) {
int ret = false;
if (s->top != Max - 1) {
s->data[++s->top] = x;
ret = true;
}
return ret;
}
//出栈
char Pop(Sqstack* s) {
char x = '0';
if (s->top != -1)
x = s->data[s->top--];
return x;
}
//读栈顶元素
char Top(Sqstack s) {
return s.data[s.top];
}
//优先级比较 a高于或等于b返回true
bool compare(char a, char b) {
bool ret = false;
if ((a == '+' || a == '-') && (b == '+' || b == '-'))
ret = true;
else if ((a == '*' || a == '/') && (b == '*' || b == '/'))
ret = true;
else if ((a == '*' || a == '/') && (b == '+' || b == '-'))
ret = true;
return ret;
}
//输入中缀表达式
void Input(char arr[]) {
printf("请输入中缀表达式:\n");
gets_s(arr, Max);
}
//中缀转后缀
void change(char arr[], Sqstack* s) {
Sqstack op;
Initstack(&op);
int i = 0;
while (arr[i] != '\0') { //依次扫描中缀表达式
if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/') {
while (!(Top(op) == '(' || IsEmpty(op))) { //栈顶元素不是( 或栈非空
if (compare(Top(op), arr[i])) { //若栈顶元素的优先级高于或等于当前运算符
Push(s, Pop(&op)); //栈顶元素出栈并加入后缀表达式
}
else break; //若栈顶元素的优先级低于当前运算符,直接退出循环
}
Push(&op, arr[i]); //当前运算符入栈
}
else if (arr[i] == '(')
Push(&op, arr[i]);
else if (arr[i] == ')') {
while (Top(op) != '(') {
Push(s, Pop(&op));
}
Pop(&op);
}
else Push(s, arr[i]);
i++;
}
while (!IsEmpty(op)) { //若栈中有剩余则全部弹出
Push(s, Pop(&op));
}
}
//输出后缀表达式
void Output(Sqstack s) {
for (int i = 0; i <= s.top; i++) {
printf("%c", s.data[i]);
}
printf("\n");
}
//初始化栈_calculator
void Initstack_cal(Sqstack_cal* s) {
s->top = -1;
}
//入栈_计算后缀表达式
bool Push_cal(Sqstack_cal* s, float x) {
bool ret = false;
if (s->top != Max - 1) {
s->data[++s->top] = x;
ret = true;
}
return ret;
}
//出栈_calculator
float Pop_cal(Sqstack_cal* s) {
float x = 0;
if (s->top != -1)
x = s->data[s->top--];
return x;
}
//读栈顶元素_calculator
float Top_cal(Sqstack_cal s) {
return s.data[s.top];
}
//char转floaat(0-9)
float charTofloat(char a) {
int ret = 0;
if (a >= '0' && a <= '9')
ret = a - '0';
return (float)ret;
}
//计算后缀表达式(操作数为0-9整数)
float Calculator_end(Sqstack s) {
Sqstack_cal n;
Initstack_cal(&n);
for (int i = 0; i <= s.top; i++) {
if (s.data[i] >= '0' && s.data[i] <= '9') {
Push_cal(&n, charTofloat(s.data[i]));
}
else if (s.data[i] == '+' || s.data[i] == '-' || s.data[i] == '*' || s.data[i] == '/') {
float x = Pop_cal(&n);
switch (s.data[i]) {
case '+':
Push_cal(&n, Pop_cal(&n) + x);
break;
case '-':
Push_cal(&n, Pop_cal(&n) - x);
break;
case '*':
Push_cal(&n, Pop_cal(&n) * x);
break;
case '/':
Push_cal(&n, Pop_cal(&n) / x);
break;
}
}
}
return Top_cal(n);
}
int main() {
char arr[Max];
Input(arr);
Sqstack s;
Initstack(&s);
change(arr, &s);
Output(s);
printf("%f", Calculator_end(s));
return 0;
}