【栈的应用】--- 中缀表达式转后缀表达式

问题描述:

如何将中缀表达式转为后缀表达式,首先我们看看他们两者的联系与区别:

  • 中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
  • 但是,这种表达让计算机来做运算是不方便的,因此,有后缀表达式:
    一个表达式E的后缀形式可以如下定义:
    (1)如果E是一个变量或常量,则E的后缀式是E本身。
    (2)如果E是E1 op E2形式的表达式,这里op是任何二元操作符,则E的后缀式为E1’ E2’ op,这里E1’和E2’分别为E1和E2的后缀式。
    (3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。
    如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+

原因分析:

我们很容易找到如何将中缀表达式转为后缀表达式,不过用栈怎么实现呢?
主要是处理下面这几种特殊情况即可:
在这里插入图片描述


代码实现:

#ifndef __STACK_H
#define __STACK_H

typedef char ElemType;

typedef  struct Stack
{
	ElemType   *stack_low;
	int          top;
	int          size;
}Stack;

void InitStack(Stack *st,  int init_size);

bool  Empty(Stack *st);

bool  Push(Stack *st, ElemType value);

bool  Pop(Stack *st);

bool Top(Stack *st, ElemType *reval);

void DestroyStack(Stack *st);

#include "stack.h"
#include <string.h>
#include<stdio.h>
#include <stdlib.h>
#include<ctype.h>

static bool Full(Stack *st)
{
	return st->top == st->size;
}

static bool AppendSpace(Stack *st)
{
	ElemType *new_space = (ElemType*)malloc(sizeof(ElemType) * st->size * 2);
	if(new_space == NULL) return false;

	for(int i = 0; i < st->size; ++i)
	{
		new_space[i] = st->stack_low[i];
	}

	free(st->stack_low);
	st->stack_low = new_space;
	st->size *= 2;

	return true;
}

void InitStack(Stack *st, int init_size)
{
	if(st == NULL)  exit(0);

	init_size = init_size > 0 ? init_size : 10;

	st->stack_low =  (ElemType*)malloc(sizeof(ElemType) * init_size);
	if(st->stack_low == NULL)  exit(0);

	st->top = 0;
	st->size = init_size;
}

bool  Empty(Stack *st)
{
	if(st == NULL) exit(0);

	return st->top == 0;
}

bool  Push(Stack *st, ElemType value)
{
	if(st == NULL) exit(0);

	if(Full(st))
	{
		if(!AppendSpace(st))
		{
			return false;
		}
	}

	st->stack_low[st->top++] = value;
	return true;
}
bool  Pop(Stack *st)
{
	if(st == NULL)  exit(0);

	if(Empty(st)) return false;

	st->top--;
	return true;
}
bool Top(Stack *st, ElemType *reval)
{
	if(st == NULL) exit(0);

	if(Empty(st)) return false;

	*reval = st->stack_low[st->top - 1];
	return true;
}
void DestroyStack(Stack *st)
{
	if(st == NULL) exit(0);

	free(st->stack_low);
	st->stack_low = NULL;
	st->top = st->size  = 0;
}

//中缀转后缀
void InfixToSuffix(char *str)
{
	if(str==NULL) return;
	Stack s;
	InitStack(&s,10);

	int i=0; //开始遍历表达式字符串的下标

	while(str[i]!='\0')
	{
		if(str[i]==' ')
		{
			i++;
			continue;
		}
		if(isdigit(str[i])) //如果是数字的情况
		{
			printf("%c",str[i]);
			if(!isdigit(str[i+1])) 
			{
				printf(" ");
			}
		}
		else if(str[i]=='(') //如果是左括号的情况
		{
			Push(&s,str[i]);
		}
		else if(str[i]==')') //如果是右括号的情况
		{
			int flag=0;
			while(!Empty(&s))
			{
				ElemType val;
				Top(&s,&val);
				Pop(&s);

				if(val=='(')
				{
					flag=1;
					break;
				}

				printf("%c ",val);
			}

			if(!flag)
			{
				printf("括号不匹配\n");
			}

		}
		else if(str[i]=='*' || str[i]=='/')
		{
			ElemType val;
			while(!Empty(&s))
			{
				Top(&s,&val);
				if(val=='(' || 
					val=='+' || 
					val=='-')  break;
				Pop(&s);
				printf("%c ",val);
			}
			Push(&s,str[i]);
		}
		else if(str[i]=='+' || str[i]=='-')
		{
			ElemType val;
			while(!Empty(&s))
			{
				Top(&s,&val);
				if(val=='(' ) break;
				Pop(&s);
				printf("%c ",val);
			}
			Push(&s,str[i]);
		}
		else 
		{
			printf("输入内容有误!\n");
			return;
		}

		i++;
	}

	while(!ElemType(&s))
	{
		ElemType val;
		Top(&s,&val);
		printf("%c ",val);
		Pop(&s);
	}
	printf("\n");

	DestroyStack(&s);
}

int main()
{
	char str[]="12*4+34/5-(56+67*4)+32";
	printf("\n");
	InfixToSuffix(str);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值