原则
- 遇到数字 :直接输出
- 遇到运算符 :输出优先级比自己大的运算符,直至遇到(,然后自己入栈
- 遇到 ( :直接入栈
- 遇到 ) :输出栈顶元素,直至遇到 (
用到 栈 这个数据结构,利用其 后进先出 的性质
转换原因(后缀表达式的优点)
- 不需要保存括号
- 对计算机来说运算简单,运算符之间不存在优先级
注意
- 右括号不入栈
- 数字不入栈,直接输出。(想保存可自己设置)
- 若输入的数字 >=10 ,因输入时当作字符串输入,需改动
- stack 不必自己定义,可用 C++ STL的stack,只需加上
#include <stack>
(下面源码里我是用自己定义的)
常用函数:
empty() pop() push() size() top()
源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 30
#define elemType int
typedef struct sqStack
{
elemType *base;
elemType *top;
int stackSize;
} sqStack, *pStack;
//top指向空格
void initStack(sqStack *s)
{
s->base = (elemType *)malloc(STACK_INIT_SIZE * sizeof(elemType));
if (!s->base)
{
printf("malloc failure\n");
exit(-1);
}
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
elemType getTop(pStack s)
{
if (s->base == s->top)
{
printf("The stack is empty !\n");
exit(-1);
}
return *(s->top - 1);
}
void push(pStack s, elemType e)
{
if (s->top - s->base >= s->stackSize)
{
s->base = (elemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(elemType));
if (!s->base)
{
printf("realloc failure\n");
exit(-1);
}
s->stackSize += STACKINCREMENT;
}
*(s->top) = e;
s->top++;
}
void pop(pStack s)
{
if (s->top == s->base)
{
printf("The stack is empty !\n");
exit(-1);
}
s->top--;
}
bool isEmpty(pStack s)
{
if (s->base == s->top)
return true;
return false;
}
int main()
{
//用字符指针输入不定长字符串(中缀表达式),超好用
char *p;
p = (char *)malloc(sizeof(char));
scanf("%s", p);
int len = strlen(p);
//初始化空栈
pStack s = (pStack)malloc(sizeof(pStack));
initStack(s);
//遍历字符串
for (int i = 0; i < len; i++, p++)
{
//数字直接输出
if (*p >= '0' && *p <= '9')
{
printf("%c", *p);
}
else
switch (*p)
{
//左括号直接入栈
case '(':
push(s, *p);
break;
//右括号不入栈,输出栈顶元素,直至栈空或遇到左括号,左括号丢弃不输出
case ')':
while (!isEmpty(s) && getTop(s) != '(')
{
printf("%c", getTop(s));
pop(s);
}
if (getTop(s) == '(')
pop(s);
break;
//一直输出优先级 >= 自己的栈顶元素,直至栈空或遇到左括号,然后自己入栈
case '*':
case '/':
while (!isEmpty(s) && (getTop(s) == '*' || getTop(s) == '/'))
{
printf("%c", getTop(s));
pop(s);
}
push(s, *p);
break;
case '+':
case '-':
while (!isEmpty(s) && getTop(s) != '(')
{
printf("%c", getTop(s));
pop(s);
}
push(s, *p);
break;
default:
break;
}
}
//遍历完若栈不为空,输出
while (!isEmpty(s))
{
printf("%c", getTop(s));
pop(s);
}
}
//计算后缀表达式的值
void calculate(char *p)
{
int len = strlen(p);
//初始化空栈
pStack s = (pStack)malloc(sizeof(pStack));
initStack(s);
//遍历字符串
for (int i = 0; i < len; i++, p++)
{
//数字直接入栈
if (*p >= '0' && *p <= '9')
{
push(s, (int)(*p - '0'));
}
//若是操作符@,弹出栈顶元素a和新的栈顶元素b,执行b @ a,将结果压入栈中
else
{
int b = getTop(s);
pop(s);
int a = getTop(s);
pop(s);
int temp = 0;
switch (*p)
{
case '+':
temp = a + b;
break;
case '-':
temp = a - b;
break;
case '*':
temp = a * b;
break;
case '/':
temp = a / b;
break;
}
push(s, temp);
}
}
//最后栈中只剩下一个元素,即表达式的值。
printf("The result is %d", getTop(s));
}