#include<stdio.h>
#include<malloc.h>
typedef struct node { //链栈节点
char data;
struct node* next;
}Node, * LinkList;
void InitStack(LinkList& top) { //初始化栈
top = (LinkList)malloc(sizeof(Node));
top->next = NULL;
}
void Push(LinkList& top, char ch) { //令ch入栈
top->data = ch;
LinkList s;
s = (LinkList)malloc(sizeof(Node));
s->next = top;
top = s;
}
char GetTop(LinkList top) { //得到栈顶元素
char ch;
ch = (top->next)->data;
return ch;
}
void Pop(LinkList& top, char& ch) { //得到栈顶元素值并出栈
LinkList p;
p = top->next;
ch = p->data;
free(top);
top = p;
}
char* ReversePolishNotation(char* s) {
LinkList s1, s2; //栈s1存放运算符,栈s2存放逆波兰式
InitStack(s1);
InitStack(s2);
Push(s1, '#'); //设#是优先级最低的运算符,入栈s1
char ch; //ch用于存放临时字符
int length = 0; //length用于计算s2长度
for (char* p = s; *p != '\0'; p++) { //遍历传入的字符数组
switch (*p)
{
//遇'('则直接入栈s1
//遇')'则将距离栈s1栈顶的最近的'('之间的运算符,逐个出栈,依次送入栈s2,此时抛弃'('
case'(':
Push(s1, *p); break;
case')':
while (GetTop(s1) != '(') {
Pop(s1, ch);
Push(s2, ch); length++;
}Pop(s1, ch); break;
//遇下列运算符,则分情况讨论:
//1.若当前栈s1的栈顶元素是'(',则当前运算符直接压入栈s1;
//2.否则,将当前运算符与栈s1的栈顶元素比较,若优先级较栈顶元素大,则直接压入栈s1中,
//否则将s1栈顶元素弹出,并压入栈s2中,直到栈顶运算符的优先级别低于当前运算符,然后再将当前运算符压入栈s1中
case'+':
case'-':
for (ch = GetTop(s1); ch != '#'; ch = GetTop(s1)) {
if (ch == '(')break;
else Pop(s1, ch); Push(s2, ch); length++;
}Push(s1, *p); break;
case'*':
case'/':
for (ch = GetTop(s1); ch != '#' && ch != '+' && ch != '-'; ch = GetTop(s1)) {
if (ch == '(')break;
else Pop(s1, ch); Push(s2, ch); length++;
}Push(s1, *p); break;
default:
Push(s2, *p); length++;
}
}
//若栈s1非空,则将栈中元素依次弹出并压入栈s2中
while (GetTop(s1) != '#') {
Pop(s1, ch);
Push(s2, ch); length++;
}
//最后将栈s2输出,逆序排列成字符串;
char* result;
result = (char*)malloc((length + 1) * sizeof(char));
int i = 0;
for (i = length - 1; i >= 0; i--) {
Pop(s2, ch);
result[i] = ch;
}
result[length] = '\0';
return result;
}
int main()
{
while (1)
{
char str[100];
int i;
for (i = 0; i < 100; i++)str[i] = '\0';
printf("请输入表达式:\n");
scanf_s("%s", str, 100);
char* result = ReversePolishNotation(str);
printf("%s", result);
}
return 0;
}