StackExpressionApply.h
#ifndef INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H
#define INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H
#include<stdio.h>
#include<string.h>
int GetOperationSymbolLever(char c);
ElemType *MidToAfterExpression(char midExpression[]);
// 中缀表达式转换为后缀表达式
// todo 当表达式操作数值大于10如何处理? 暂时用0~9之间的数值实现
ElemType *MidToAfterExpression(char midExpression[]) {
// 初始化后缀表达式
ElemType *afterExpression = (ElemType*) malloc(sizeof (ElemType) * strlen(midExpression));
// 记录当前后缀表达式元素的下标
int index = 0;
// 初始化一个栈存储不确定运算顺序的运算符
LinkStack *stack = NULL;
for (int i = 0; i < strlen(midExpression); i++) {
char item = midExpression[i];
// 若为数字直接加入后缀表达式
if (item >= '0' && item <= '9') {
afterExpression[index] = item;
// 下标后移一位
index++;
} else if (item == '(') {
// 左括号直接入栈
Push(&stack, item);
} else if (item == ')') {
// )右括号依次出栈运算符直接匹配到左括号(
// 获取到一个栈顶元素
ElemType top;
Pop(&stack, &top);
while (top != '(') {
// 将运算符加入到后缀表达式
afterExpression[index] = top;
index++;
// top不为左括号就一直出栈
Pop(&stack, &top);
}
} else if (item == '+' || item == '-' || item == '*' || item == '/') {
ElemType top;
GetTop(stack, &top);
// 判断栈是否为空或栈顶元素为左括号 符合条件直接入栈
if (IsEmpty(stack) || top == '(') {
Push(&stack, item);
} else {
// 判断优先级 当前运算符大于栈顶元素的优先级则入栈
if (GetOperationSymbolLever(top) < GetOperationSymbolLever(item)) {
Push(&stack, item);
// 进入当前条件 就不指向下面的循环 进入下一次循环
continue;
}
// 否则依次出栈直到遇到优先级比它低的运算符或遇到左括号
while ((GetOperationSymbolLever(top) >= GetOperationSymbolLever(item) ||
top != '(') && !IsEmpty(stack)) {
Pop(&stack, &top);
afterExpression[index] = top;
index++;
}
// 再将当前运算符入
Push(&stack, item);
}
} else {
// 字符不符合条件 终止函数运行 打印提示信息
printf("the input data is not allowed");
return NULL;
}
}
ElemType top;
// 最后将栈底元素依次出栈加入到后缀表达式
while (!IsEmpty(stack)) {
Pop(&stack, &top);
afterExpression[index] = top;
index++;
}
return afterExpression;
}
// 获取运算符优先级
int GetOperationSymbolLever(char c) {
if (c == '*' || c == '/') return 2;
return 1;
}
#endif //INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H
LinkStack.c
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
typedef struct LinkStack {
ElemType data;
struct LinkStack *next;
} LinkStack;
int Push(LinkStack **L, ElemType e);
int IsEmpty(LinkStack *L);
int GetTop(LinkStack *L, ElemType *e);
int Pop(LinkStack **L, ElemType *e);
// 入栈
// 注:必须使用二级指针 因为要修改指针变量的地址 用一级指针无法更改
int Push(LinkStack **L, ElemType e) {
// 新建节点
LinkStack *s = (LinkStack *) malloc(sizeof(LinkStack));
// 入栈
s->next = *L;
s->data = e;
*L = s;
printf("%c进栈\n", e);
return 1;
}
// 判断是否为空
int IsEmpty(LinkStack *L) {
if (L == NULL) return 1;
return 0;
}
// 返回栈顶元素
int GetTop(LinkStack *L, ElemType *e) {
if (IsEmpty(L)) {
return -1;
}
// 取出栈顶元素`
*e = L->data;
return 1;
}
// 出栈
// 注:必须使用二级指针 因为要修改指针变量的地址 用一级指针无法更改
int Pop(LinkStack **L, ElemType *e) {
*e = (*L)->data;
*L = (*L)->next;
return 1;
}
// 销毁栈
void DestroyStack(LinkStack **L) {
LinkStack *temp;
// 当头节点为NULL时 销毁结束
while ((*L) != NULL) {
temp = *L;
*L = (*L)->next;
free(temp);
}
}
main.c
#include <stdio.h>
#include "sources/StackExpressionApply.h"
int main() {
char operations[] = "2+9*(3-4)-3/6+4*1";
char *expression;
expression = MidToAfterExpression(operations);
for (int i = 0; i < strlen(expression); ++i) {
printf("%c", expression[i]);
}
printf("\n");
return 0;
}