中缀表达式转成后缀表达式,以及后缀求值

本文介绍了如何将中缀表达式转换为后缀表达式以及如何计算后缀表达式。算法使用数组栈,核心代码包括InfixToPostfix()和calculatePostfix()。在中缀转后缀过程中,根据优先级和括号规则决定符号入栈时机。计算后缀表达式时,遇到运算符便进行运算,确保有足够的数字进行计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/************************************************************
*中缀表达式转成后缀表达式计算后缀表达式
*使用数组栈完成
*问题描述:  输入一个中缀表达式: a+b*c+(d*e+f)+g,转成后缀表达式
*算法: 1.如果是数字,则直接输出;
        2.如果是计算符或者括号,则利用栈判断选择何种操作
        2.1 如果栈空,或者入栈元素的优先级高于栈顶元素(或栈顶元素是'('),或者入栈元素是'(',则入栈符号入栈,且栈顶不出栈
		    例如: 栈顶元素是+ ,入栈符号是* ,则*直接入栈
		2.2 如果入栈元素是')',则入栈元素不入栈,且栈顶元素一直出栈到'('为止('('也出栈)
		2.3 如果入栈元素优先级不高于栈顶元素,则栈顶元素一直出栈,直到栈空,栈顶元素的优先级高于栈顶元素(或栈顶元素是'('), 入栈符号再入栈
		2.4 输入读完后,如果栈不空,则直接输出栈中所有符号
*核心代码:  InfixToPostfix()


*计算后缀表达式   
*问题描述:
*算法: 1. 数字直接进栈,
       2. 遇到运算符,如果栈中有2个数字,则进行运算,且运算结束后出栈,结果入栈;如果少于2个数字,则报错。
*核心代码:calculatePostfix() 
*
*author: fangchang
*date:   2016/03/26
*time:   20:18
**************************************************************/

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

#define N 100                    //最多输入N个数字和计算符


void answer();
int calculatePostfix();                                   //计算后缀表达式
int isSymbol(char * str);                                 //判断str是否是符号
int calculate(int firstNum, int secondNum, char * str);   //计算单次的运算
void checkSymbol(char str[][N],int len );                 //检查输入是否含有无法参与运算的字符

void InfixToPostfix();                                       //中缀表达式转成后缀表达式
BOOL symbolCmp(int firstSymbol, int secondSymbol);           //比较两个符号的优先级
int main() {
	InfixToPostfix();   //中缀变成后缀
	//answer();         //计算后缀表达式
	fflush(stdin);
	getchar();
	return 1;
}

void answer() {
	printf("result is : %d\n",calculatePostfix());
}

int calculatePostfix() {                                     //计算后缀表达式
	char str[N][N];
	int i=0;
	int len=0;
	int firstNum,secondNum,result;
	Stack s = createStack();
	memset(str,'\0',N*N);                                                //字符串数组初始化为'\0'
	while(scanf("%s",str[i]) && 0!=strcmp(str[i],"#") && i<N) {          //读入字符串,输入"#"时结束
		i++;
	}
	len=i;
	checkSymbol(str,len);                                               //输入检查,如果有不能参与运算的符号则退出
	for(i=0;i<len;++i) {
		if(isSymbol(str[i])) {                                          //core code  处理符号
			if(!isEmpty(s)) {                                          
				secondNum=top(s);
				pop(s);
				if(!isEmpty(s)) {
					firstNum = top(s);
					pop(s);
					result = calculate(firstNum,secondNum,str[i]);
					push(s,result);
				}
				else {
					printf("error: one number cannot calculate!\n");
					return -1;
				}
			}
			else {
					printf("error: zero number cannot calculate!\n");
					return -1;
				}
		}
		else {                                                            //数字直接进栈
			push(s,strtol(str[i],NULL,10));                               //strtol(),将字符串转成数字
		}
	}
	return top(s);
}

int isSymbol(char * str) {                                   //判断是否是计算符
	if(0==strcmp(str,"+") ) {
		return TRUE;
	}
	else if(0==strcmp(str,"-") ) {
		return TRUE;
	}
	else if(0==strcmp(str,"*") ) {
		return TRUE;
	}
	else if(0==strcmp(str,"/") ) {
		return TRUE;
	}
	else if(0==strcmp(str,"(") ) {
		return TRUE;
	}
	else if(0==strcmp(str,")") ) {
		return TRUE;
	}
	return FALSE;
}

int calculate(int firstNum, int secondNum, char * str) {
	if(0==strcmp(str,"+")) {
		return firstNum+secondNum;
	}
	else if(0==strcmp(str,"-") ) {
		return firstNum-secondNum;
	}
	else if(0==strcmp(str,"*") ) {
		return firstNum*secondNum;
	}
	else if(0==strcmp(str,"/") ) {
		return secondNum==0? 0 : firstNum/secondNum;
	}
	return 0;
}

void checkSymbol(char str[][N],int len ) {
	int i,j;
	for(i=0;i<len;++i) {
		if(isSymbol(str[i])) {
			continue;
		}
		for(j=0;str[i][j]!='\0';++j) {
			if(! isdigit(str[i][j]) ) {
				printf("has special symbol!\n");
				return ;
			}
		}
	}
}

void InfixToPostfix() {      
	char str[N][N];
	char tmp[N][N];
	Stack s = createStack();
	int i=0;
	int j=0;
	int len;
	int toSymbol;
	memset(str,'\0',N*N);
	memset(tmp,'\0',N*N);
	while(scanf("%s",str[i]) && (0!=strcmp(str[i],"#")) && (i<N) ) {              //输入前缀表达式,"#"结束
		i++;
	}
	len=i;
	for(i=0;i<len;++i) {
		if(isSymbol(str[i])) {
			toSymbol = str[i][0];
			if(isEmpty(s) || '(' == str[i][0] || '('==top(s) ) {    //直接入栈的情况
				push(s,toSymbol);
			}
			else if( ')' == toSymbol ) {                          //遇到')',直接出栈
				while( !isEmpty(s) && '('!=top(s)) {
					tmp[j++][0] = top(s);
					printf("%c  ",top(s));
					pop(s);
				}                                  
					pop(s);                                        //出栈'('                                    
			}
			else {                                                 //需要判断栈顶元素和将要入栈的元素的优先级
				while(!isEmpty(s) && '('!=top(s) && 0==symbolCmp(top(s),toSymbol)) {  //出栈的情况
					tmp[j++][0] = top(s);
					pop(s);
				}
				push(s,toSymbol);                 //栈空,top(s)='(',将要入栈元素优先级低于栈顶元素,则入栈
			}

		}
		else {
			memcpy(tmp[j++],str[i],strlen(str[i]));           //数字直接输出到tmp数组中
		}
	}
	while(!isEmpty(s)) {                                      //输入结束后,判断符号栈是否为空,不空则直接全部出栈
		tmp[j++][0] = top(s);
		pop(s);
	}
	for(i=0;i<j;++i) {                                         //打印后缀表达式结果
		printf("%s ",tmp[i]);
	}
}


BOOL symbolCmp(int firstSymbol, int secondSymbol) {
	if ('+'==firstSymbol || '-'==firstSymbol) {
		if ('+'==secondSymbol || '-'==secondSymbol) {
			return 0;                                     //优先级相等,默认相等时,firstSymbol高
		}
		return 1;                                         //secondSymbol优先级高
	}
	else {                                                //其他情况都是firstSymbol高
		return 0;                                        
	}
}
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值