栈的应用——四则运算(逆波兰表达式)

逆波兰表达式

  • 前缀表达式、中缀表达式、后缀表达式(逆波兰表达式)都是四则运算的表达方式,用以四则运算表达式求值 ,即数学表达式的求值
    (1)a - b * c + d:中缀表达式 (Infix Notation),原因是运算符号在两个运算对象的中间。
    (2)+ - a * b c d:前缀表达式 (Prefix Notation),又叫波兰表达式,运算符在运算对象前面,又称为波兰表达式。
    (3)a b c * - d +:后缀表达式 (Suffix Notation),又叫逆波兰表达式,运算符在运算对象后面,又称为逆波兰表达式。

  • 后缀表达式的优点
    (1)相较于前缀表达式更易于转换,最左边一定为数字。
    (2)不用括号,依靠运算顺序确定运算符的优先级。
    (3)更符合计算机的计算方式。计算机通过从左至右读取后缀表达式,就可以将遇到的运算对象压入栈,在遇到运算符时就弹出两个运算对象,完成计算,再将结果压入栈。最后留在栈中的就是计算结果。

int Compute(char s[81])
{
	int *sval;	//操作数栈 
	char *sop;	//运算符栈 
	int valtop=-1;
	int optop=-1;
	int x1,x2;
	char op;
	sval=(int *)malloc(N*sizeof(int));
	sop=(char *)malloc(N*sizeof(char));
	sop[++optop]='@';
	int i=0;
	while(s[i]){		
		if(s[i]>='0'&&s[i]<='9')//字符串四种情况:数字,运算符,左括号,右括号 
		{	
			int y=0;
			while('0'<=s[i]&&s[i]<='9')
			{			
				y=y*10+s[i]-'0';	//将连续的数字字符串转换为数字 
				i++;
			}
			
			sval[++valtop]=y;	//Y用来接收转化的数字 
			
			i--;
		}
		else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/')		//运算符 
		{
			while(Level(s[i])<=Level(sop[optop]))		//即将入栈的运算符优先级低于栈中运算符优先级 
			{
				x1=sval[valtop--];
				x2=sval[valtop--];
				op=sop[optop--];
				sval[++valtop]=Cal(x1,x2,op);
			}
			sop[++optop]=s[i];
		}
		else if(s[i]=='(')
		{
			sop[++optop]='(';	
		}
		else if(s[i]==')'){
			while(sop[optop]!='('){
				x1=sval[valtop--];
				x2=sval[valtop--];
				op=sop[optop--];
				sval[++valtop]=Cal(x1,x2,op);
			}
			optop--;
		}
		
		i++;
	}
	while(optop)
	{
		x1=sval[valtop--];
		x2=sval[valtop--];
		op=sop[optop--];
		sval[++valtop]=Cal(x1,x2,op);
	}
	return sval[valtop];
}

运算符优先级判断

nt Level(char a)		//判断运算符的优先顺序 
{
	switch(a){
		case'+':
		case'-':return 1;break;
		case'*':
		case'/':return 2;break;	
		case'@':return 0;break;
		
	}
} 

计算

int Cal(int x1,int x2,char op)
{
	switch(op){
		case'+':return x2+x1;
		case'-':return x2-x1;
		case'*':return x2*x1;
		case'/':return x2/x1;
	}
}

完整四则运算代码

#include
#include
#include
#define N 81
//测试(1+2)*3+2-1 括号用英文输入	 
int Level(char a);		//比较运算符的优先顺序 
int Cal(int x1,int x2,char op);
int Compute(char s[81]);

int main(void)
{
	char s[81];
	int value;
	printf("请输入一个中缀表达式:\n");
	gets(s);
	value=Compute(s);
	printf("%s=%d\n",s,value);
}

int Compute(char s[81])
{
	int *sval;	//操作数栈 
	char *sop;	//运算符栈 
	int valtop=-1;
	int optop=-1;
	int x1,x2;
	char op;
	sval=(int *)malloc(N*sizeof(int));
	sop=(char *)malloc(N*sizeof(char));
	sop[++optop]='@';
	int i=0;
	while(s[i]){		
		if(s[i]>='0'&&s[i]<='9')//字符串四种情况:数字,运算符,左括号,右括号 
		{	
			int y=0;
			while('0'<=s[i]&&s[i]<='9')
			{			
				y=y*10+s[i]-'0';	//将连续的数字字符串转换为数字 
				i++;
			}
			
			sval[++valtop]=y;	//Y用来接收转化的数字 
			
			i--;
		}
		else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/')		//运算符 
		{
			while(Level(s[i])<=Level(sop[optop]))		//即将入栈的运算符优先级低于栈中运算符优先级 
			{
				x1=sval[valtop--];
				x2=sval[valtop--];
				op=sop[optop--];
				sval[++valtop]=Cal(x1,x2,op);
			}
			sop[++optop]=s[i];
		}
		else if(s[i]=='(')
		{
			sop[++optop]='(';	
		}
		else if(s[i]==')'){
			while(sop[optop]!='('){
				x1=sval[valtop--];
				x2=sval[valtop--];
				op=sop[optop--];
				sval[++valtop]=Cal(x1,x2,op);
			}
			optop--;
		}
		
		i++;
	}
	while(optop)
	{
		x1=sval[valtop--];
		x2=sval[valtop--];
		op=sop[optop--];
		sval[++valtop]=Cal(x1,x2,op);
	}
	return sval[valtop];
}

int Level(char a)		//判断运算符的优先顺序 
{
	switch(a){
		case'+':
		case'-':return 1;break;
		case'*':
		case'/':return 2;break;	
		case'@':return 0;break;
		
	}
} 
int Cal(int x1,int x2,char op)
{
	switch(op){
		case'+':return x2+x1;
		case'-':return x2-x1;
		case'*':return x2*x1;
		case'/':return x2/x1;
	}
}

你可能感兴趣的:(数据结构)