中缀表达式转化为后缀表达式(逆波兰表达式)

1.将中缀表达式转化为后缀表达式

后缀表达式也叫作逆波兰表达式,主要是运用栈的后进先出思想,下面就讲讲我自己的思考,

假设中缀表达式为:2*(2+1)-6(4-2)#,则后缀表达式为:2 2 1 + * 6 4 2 - / -;

首先依次遍历中缀表达式,遇到操作数字符则直接输出(数字字符大小区间在 ‘0’~‘9’),遇到操作符字符则依次入栈,其中操作符入栈条件:

  1. 若栈中没有元素,即栈空,无条件入栈。
  2. 若为左括号“( ”,无条件入栈。
  3.  若为右括号" ) ",则依次输出栈中的运算符,直到遇到左括号“(”为止。
  4. 若为非括号操作符,则比较此时遍历到的操作符和栈顶元素,并判断元素优先级(优先级和平常运算的先后一样),如果栈顶的元素优先级较高或者相等,则弹出栈顶元素并输出,将遍历到的操作符入栈。若遍历的操作符优先级较高,则直接入栈。
  5. 遍历到“#”时,结束遍历,判断栈是否为空,若栈不为空,依次输出栈顶元素,直至栈为空。

注意:右括号“)”不进栈,只是为了更好地表达,实际不进栈

也可以参考这篇,比较详细:中缀表达式转换为后缀表达式

附上自己写的代码吧!!

// nibolanbiaodashi.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"

typedef  char Elemtype; 
#define STACKINITSIZE 100
#define STACKINCREMENT 10


typedef struct SQSTACK{
	Elemtype *top;
	Elemtype *base;
	int stacksize;

}Sqstack;

typedef struct{
	Elemtype data[STACKINITSIZE];
	int length;

}SqList;

void InitList(SqList *L)
{
	(*L).length=0;

}

void InitStack(Sqstack *S)
{
	(*S).base=(Elemtype *)malloc(STACKINITSIZE * sizeof(Elemtype));
	(*S).top=(*S).base;
	(*S).stacksize=STACKINITSIZE;
}

void Push(Sqstack *S,Elemtype e)
{
	if((*S).top-(*S).base>=(*S).stacksize)
	{
		(*S).base=(Elemtype *)realloc((*S).base,((*S).stacksize+STACKINITSIZE)*sizeof(Elemtype));
		(*S).top=(*S).base+(*S).stacksize;
		(*S).stacksize=(*S).stacksize+STACKINCREMENT;
	}
	*((*S).top)=e;
	(*S).top++;
}

void Pop(Sqstack *S,Elemtype *e)
{
	if((*S).top == (*S).base)
		return;
	e=(*S).top;
	(*S).top--;

}

void GetPop(Sqstack S,Elemtype *e)
{
	if(S.base==S.top)
		return;
	*e=*(S.top-1);

}

int EmptyStack(Sqstack S)
{
	if(S.base == S.top)
		return 1;
	return 0;

}

int Precede(Elemtype e,Elemtype a)
{
	Elemtype book;
	if((e == '+'||e == '-') && (a == '+'||a == '-'))
		book='=';
	if((e == '+'||e == '-') && (a == '*'||a == '/'))
		book='<';
	if((e == '*'||e == '/') && (a == '+'||a == '-'))
		book='>';
	if((e == '*'||e == '/') && (a == '*'||a == '/'))
		book='=';
	if(e=='(')
		book='<';
	return book;

}

void InversePolandExpression(Sqstack S,Elemtype str[],SqList *L)//逆波兰
{
	int i=0,j=0;
	Elemtype book;
	Elemtype e;
	
	
	printf("逆波兰表达式:\n");
	while(str[i]!='#')
	{
		
		if(str[i]>='0' && str[i]<='9')
		{
			(*L).data[j]=str[i];
			(*L).length++;
			j++;
			printf(" %c ",str[i]);
		}
		else   
		{
			if(str[i]=='(')
				Push(&S,str[i]);
			if(str[i]==')')
			{
				GetPop(S,&e);
				while(e!='(')
				{
					Pop(&S,&e);
					(*L).data[j]=e;
					j++;
					(*L).length++;
					printf(" %c ",e);
					GetPop(S,&e);
					if(e=='(')
						Pop(&S,&e);
				}
			
			}
			if(str[i]=='+' || str[i]=='-' || str[i]=='*' || str[i]=='/')
			{
				if(EmptyStack(S))
					Push(&S,str[i]);
				else
				{
					GetPop(S,&e);	
					book=Precede(e,str[i]);
					switch(book)
					{
						case '<' :
							Push(&S,str[i]);
							break;
						case '=' :
							Pop(&S,&e);
							(*L).data[j]=e;
							j++;
							(*L).length++;
							printf("%c",e);
							Push(&S,str[i]);
							break;
						case '>' :
							Pop(&S,&e);
							(*L).data[j]=e;
							j++;
							(*L).length++;
							printf("%c",e);
							Push(&S,str[i]);
							break;
					}
				}
			}
		}

		i++;

	}
	
	while(!EmptyStack(S))
	{
		GetPop(S,&e);
		(*L).data[j]=e;
		j++;
		(*L).length++;
		printf(" %c ",e);
		Pop(&S,&e);
	}
	
	printf("\n");
}

/*void print(SqList *L)
{
	int i=0;
	while(i<(*L).length)
	{
		printf("%c",(*L).data[i]);
		i++;
	}
	printf("\n");

}*/


int Calculate(Elemtype a,Elemtype b,Elemtype OPTR)
{
	int n;
	if(OPTR=='+')
	{
		n=(a-48)+(b-48);
	}
	if(OPTR=='-')
	{
		n=(b-48)-(a-48);
	}
	if(OPTR=='*')
	{
		n=(a-48)*(b-48);
	}
	if(OPTR=='/')
	{
		n=(b-48)/(a-48);
	}
	return n;
}

void calvalInverPoland(SqList L)//后缀表达式求值
{
	int i=0;
	int n;
	Elemtype ch;
	Elemtype a,b,e;
	Sqstack OPND;
	InitStack(&OPND);
	printf("逆波兰表达式求值 :  ");
	
	while(i<L.length)
	{
		
		if(L.data[i]>='0' && L.data[i]<='9')
		{
			Push(&OPND,L.data[i]);
		}
		else
		{
			GetPop(OPND,&a);
			Pop(&OPND,&a);
			GetPop(OPND,&b);
			Pop(&OPND,&b);
			
			n=Calculate(a,b,L.data[i]);
			ch=n+48;
			Push(&OPND,ch);
		
		}
		i++;
	}
	GetPop(OPND,&e);
	printf("%c",e);
	printf("\n");
}

int main(int argc, char* argv[])
{
	Sqstack S;
	
	SqList L;
	char str[20]="2*(2+1)-6/(4-2)#";
	printf("Please end with '#'\n");

	//scanf("%s",str);
	
	InitList(&L);
	InitStack(&S);
	

	InversePolandExpression(S,str,&L);
	
	calvalInverPoland(L);
	
	return 0;
}


后面因为临时加入了后缀表达式求值,就用了一个线性表来储存后缀表达式。

猜你喜欢

转载自blog.csdn.net/x_xhuashui/article/details/84329952