栈的练习:栈采用顺序栈存储,试编写程序实现将表达式转换成后缀表达式输出。例如,输入表达式: a+b/c-(d*e+f)*g 输出其后缀表达式:abc/+de*f+g*-

题目

栈采用顺序栈存储,试编写程序实现将表达式转换成后缀表达式输出。

例如,输入表达式:      a+b/c-(d*e+f)*g

      输出其后缀表达式:abc/+de*f+g*-

分析

将表达式转化为后缀表达式的思想为:输入表达式,遇到数字或
字母表达式就输出;
遇到运算符就进行入栈出栈操作。
**入栈出栈的操作规则为**:
首先,需判断当前符号运算符优先级与栈顶符号运算符优先级的大小,
若栈顶>当前:栈顶元素出栈,当前元素入栈
若栈顶=当前:栈顶元素出栈,并且当前元素入栈
若栈顶<当前:当前元素入栈
总原则就是谁的优先级大,就要抢占别人位置,但是每次必入栈
若遇到'(':直接入栈
若遇到')':出栈所有运算符,直到遇到')'
为了让第一个运算符也能有(比较)对象,将栈底元素人为设为'#',
并赋予极小优先级0

代码

#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 1000
#define STACKINCREMENT 10
#define OVERFLOW -2
#define OK 1
#define ERROR 0

typedef char Selemtype;
typedef int Status;

//结构体定义 
typedef struct Sqstack
{
	char *top,*base;
	int stackment;
}Sqstack;

//空顺序栈的构建
 Status Initstack(Sqstack &s)
 {
 	s.base=(Selemtype*)malloc(STACK_INIT_SIZE*sizeof(Selemtype));
 	if(!s.base)exit(OVERFLOW);
 	s.top=s.base;
 	s.stackment=STACK_INIT_SIZE;
 	return OK; 
 }
 
//元素入栈
Status Push(Sqstack &s,char e)
{
	*s.top=e; 
	s.top++;
	return OK;
}  
//元素出栈
Status Pop(Sqstack &s)
{
	if(s.top==s.base)
		return ERROR;
	printf("%c",*(--s.top));
		return OK;
}


//设置运算符优先级 ,数字越大优先级越高
Status SetPriority(char e) 
{
	switch(e)
	{
		case '#':
			return 0;
		case '(':
			return 1;
		case '+':
			return 3;
		case '-':
			return 3;
		case '*':
			return 5;
		case '/':
			return 5;
		default:
			return -1;
			
	}		
}

//将表达式转化为后缀表达式   a+b/c-(d*e+f)*g  转化为 abc/+de*f+g*-
Status Turn(Sqstack &s,char express[])//栈s用来存储转化后的后缀表达式, 字符串数组express[]用来转达待转化的原表达式 
{
	int i; 
	Push(s,'#');	;//把栈底元素'#'入栈 
	for(i=0;express[i]!='0';i++)
    {
		if(express[i]>='a'&&express[i]<='z')
			printf("%c",express[i]);
		else if(express[i]=='(')//若遇到'(':直接入栈
			Push(s,express[i]);
		else if(express[i]==')')//若遇到')':出栈所有运算符,直到遇到')'
			{
				while(*(--s.top)!='(')
				{
					s.top++;
					Pop(s);
				}	
			}

		else 
		{
			if(SetPriority(express[i])>SetPriority(*(s.top-1))) //若栈顶<当前:当前元素入栈
				{
					Push(s,express[i]);	
				}
			else if(SetPriority(express[i])==SetPriority(*(s.top-1))) //若栈顶=当前:栈顶元素出栈,并且当前元素入栈
				{
					Pop(s);
					Push(s,express[i]);		
				}
			else if(SetPriority(express[i])<SetPriority(*(s.top-1))) //若栈顶>当前:栈顶元素一直出栈,直到当前元素入栈
				{
					while(SetPriority(express[i])<SetPriority(*(s.top-1))) 
					{
						Pop(s);
					}
					if(SetPriority(express[i])>SetPriority(*(s.top-1))) //若栈顶<当前:当前元素入栈
					{
						Push(s,express[i]);	
					}
					else if(SetPriority(express[i])==SetPriority(*(s.top-1))) //若栈顶=当前:栈顶元素出栈,并且当前元素入栈
					{
						Pop(s);
						Push(s,express[i]);		
					}
					
				}
		}//else	
		
	}//for
	while(s.top!=s.base+1)
			Pop(s);
	
}//turn

 
//主函数 运行 
int main()
{
	Sqstack s;
	Initstack(s);
	char express[]= "a+b/c-(d*e+f)*g0";
	printf("原表达式为:\n");
	for(int i=0;express[i]!='0';i++)
	      printf("%c",express[i]);
 	printf("\n");
	printf("后缀表达式为:\n");
	Turn(s,express);
}

附运行结果如下
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值