/************************************************************
*中缀表达式转成后缀表达式计算后缀表达式
*使用数组栈完成
*问题描述: 输入一个中缀表达式: 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.
中缀表达式转成后缀表达式,以及后缀求值
最新推荐文章于 2022-11-08 23:29:57 发布