比如有中缀表达式:1+(2-3)*4+10/5
--> 1+(2 3 -)*4 + 10 / 5
--> 1+ (2 3 - 4 * )+ 10 / 5
--> 1 2 3 - 4 * + 10 / 5
--> 1 2 3 - 4 * + 10 5 / +
转换为后缀表达式为:1 2 3 - 4 * + 10 5 / +
1.转化思路
从左到右遍历中缀表达式的每一个数字和符号,若是数字则直接输出,若是符号了,则判断与其栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输入,直到遇到左括号或栈空才将最后的+号入栈。
// 栈-后缀表达式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS //为了避免scanf函数报错
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define InitSize 20
#define IncrementSize 10
#define MAXBUFFER 10
typedef char ElimentType;
typedef struct
{
ElimentType* top;
ElimentType* base;
int StackSize;
}sqStack;
void InitStack(sqStack* s)
{
s->base = (ElimentType*)malloc(InitSize * sizeof(ElimentType));
if (!s->base)
{
exit(0);
}
s->top = s->base;
s->StackSize = InitSize;
}void Push(sqStack* s, ElimentType c)
{
if (s->top - s->base >= s->StackSize)
{
s->base = (ElimentType*)realloc(s->base, (s->StackSize + IncrementSize) * sizeof(ElimentType));
if (!s->base)
{
exit(0);
}
s->top = s->base + s->StackSize;
s->StackSize = s->StackSize + IncrementSize;
}
*(s->top) = c;
s->top++;
}
void Pop(sqStack* s, ElimentType* c)
{
if (s->top == s->base)
{
return;
}
s->top--;
*c = *(s->top);
}
int Stacklen(sqStack s)
{
int len = 0;
len = s.top - s.base;
return len;
}
int main()
{
sqStack s;
InitStack(&s);
char c,temp;
int len;
printf("请输入一个中缀表达式,以#结束\n");
scanf("%c", &c);
while (c != '#')
{
while ((c >= '0') && (c <= '9'))
{
printf("%c", c);
scanf("%c", &c);
if ((c < '0') || (c > '9'))
{
printf(" ");
}
}
if (c == ')') //如果输入的是),需要检验栈里面是否有(, 如果有(,需要将括号里面的运算符弹出
{
Pop(&s, &c);
while (c != '(')
{
printf("%c ", c);
Pop(&s, &c);
}
}
else if((c=='+') || (c=='-')) //关键代码
{
temp = c; //临时变量temp用于存放当前的+-运算符
if (!Stacklen(s)) //如果栈为空,则直接将+-入栈
{
Push(&s, c);
}
else //栈不为空,判断栈内的优先级
{
do
{
Pop(&s, &c); //弹出栈顶元素,
if (c == '(') //如果栈顶元素是(,则把 ( 入栈
{
Push(&s, c);
}
else //如果栈顶元素不是(,那么该栈顶元素肯定就是*/),直接printf
{
printf("%c ", c);
}
} while (Stacklen(s) && (c != '(')); //栈为空,且括号内的运算符都pop之后,则退出
Push(&s, temp);//在所有高优先级的运算符弹出来之后,最后把当前的+-入栈
}
}
else if ((c == '*') || (c == '/') || (c == '('))
{
Push(&s, c);
}
else if (c == '#') //
{
break;
}
else //种种可能都不是的话,则是用户输入错误
{
printf("用户输入错误!\n");
return -1;
}
scanf("%c", &c);
}
while (Stacklen(s)) //最后把栈内的元素全部输出
{
Pop(&s, &c);
printf("%c ", c);
}
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
运行结果: