1. 程式人生 > >中綴表示式轉化為字尾表示式(逆波蘭表示式)

中綴表示式轉化為字尾表示式(逆波蘭表示式)

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;
}


後面因為臨時加入了字尾表示式求值,就用了一個線性表來儲存字尾表示式。