数据结构-----栈(逆波兰表达式)----中缀转后缀
2014-04-02 22:05
323 查看
一、中缀表达式转换为逆波兰式
将一个普通的中序表达式转换为逆波兰表达式的一般算法是:
1、首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
2、读入一个中缀表达式,为了方便起见,可在其最右端追加一个最低优先级运算符(如:#号)。(这样做的目的是,最后读入#号运算符时将运算符栈中所有运算符都输出)。
3、从左至右扫描该中缀表达式,如果当前字符是数字,则分析到该数字串的结束,并将该数字串直接输出。
4、如果不是数字,该字符则是运算符,此时需比较该运算符与运算符栈顶运算符的优先关系:
(1)、若该运算符优先级高于栈顶运算符优先级别(或栈为空),则直接将该运算符压入运算符栈中;
(2)、若该运算符优先级小于或等于此运算符栈顶的运算符,则弹出栈顶运算符并输出,重复比较、输出,直到栈为空或该运算符优先级高于栈顶运算符,然后将该运算符入栈。
5、重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,输出结果便是中缀表达式转化为逆波兰表示的简单算术表达式。
二、代码实现
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
typedef char ElemType;
typedef struct//栈
{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack;
void InitStack(sqStack *s)//创建一个以数组进行存储的栈
{
s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if( !s->base )
exit(0);
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
void Push(sqStack *s, ElemType e)//压栈
{
// 栈满,追加空间
if( s->top - s->base >= s->stackSize )
{
s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
if( !s->base )
exit(0);
s->top = s->base + s->stackSize;
s->stackSize = s->stackSize + STACKINCREMENT;
}
*(s->top) = e; // 存放数据
s->top++;
}
void Pop(sqStack *s, ElemType *e)//出栈,将数据存储于e
{
if( s->top == s->base )
return;
*e = *--(s->top); // 将栈顶元素弹出并修改栈顶指针
}
int StackLen(sqStack s)//返回栈中有效元素的长度
{
return (s.top - s.base);
}
int main()
{
sqStack s;
char c, e;
InitStack( &s );
printf("请输入中缀表达式,以#作为结束标志:");
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, &e);
while( '(' != e )
{
printf("%c ", e);
Pop(&s, &e);
}
}
else if( '+'==c || '-'==c )
{
if( !StackLen(s) )//如果栈为空,则直接压栈
{
Push(&s, c);
}
else
{
do
{
Pop(&s, &e);//退出栈顶元素,若是'(',直接将'+'或'-'压入栈中(得现将'('压栈)
if( '(' == e )
{
Push(&s, e);//将'('压栈
}
else//若是'+','-','*','/',则向屏幕输出此栈顶元素
{
printf("%c ", e);
}
}while( StackLen(s) && '('!=e );
Push(&s, c);//将'+'或'-'压栈
}
}
else if( '*'==c || '/'==c || '('==c )//遇到'*'、'/'、'(',直接压栈
{
Push(&s, c);
}
else if( '#'== c )
{
break;
}
else
{
printf("\n出错:输入格式错误!\n");
return -1;
}
scanf("%c", &c);
}
while( StackLen(s) )//将栈中的剩余操作符全部输出
{
Pop(&s, &e);
printf("%c ", e);
}
return 0;
}
三、效果展示
相关文章推荐
- 【基础知识】【中缀转逆波兰(后缀)表达式】
- 【基础知识】【中缀转逆波兰(后缀)表达式】
- 逆波兰表达式-中缀转后缀(计算器)
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 中缀表达式转后缀表达式(逆波兰)
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 中缀表达式转后缀表达式(逆波兰式)的C++代码
- 数据结构-前缀、中缀、后缀表达式
- 前缀,中缀,后缀波兰表达式
- 数据结构之中缀表达式转前缀和后缀
- 【数据结构】逆波兰表示法(RPN):中缀表达式转后缀表达式
- 逆波兰表达式计算(后缀表达式,中缀转后缀)
- 中缀转后缀表达式||后缀表达书计算
- java数据结构与算法之中缀表达式转为后缀表达式的方法
- 第六周数据结构实践——后缀表达式(栈)【项目5 - 后缀表达式】
- 中缀表达式转换为后缀表达式
- 前缀 中缀 后缀 波兰式 逆波兰式
- [数据结构] 表达式求值(转化为后缀表达式再求值或直接求值)
- 前缀、中缀、后缀表达式
- 【数据结构】用栈实现对后缀表达式的计算