中缀转后缀表达式c/c++描述(下)

  整个程序的功能是先把中缀表达式转换成标准的中缀表达式,所有数据与运算符之间有一个空格,运算符之间,也有一个空格(我们把括号也当作运算符)。若空格多于一个则只保留一个空格。这个功能见transferToNormal函数,然后由函数transferMidToPost完成中缀到后缀表达式的转换。
然后由函数computor计算后缀表达式的值。代码如下:(见名知意,很好理解)
  这是主函数main:

#include<iostream>
using namespace std;
#define MAXSIZE 50

extern void transferMidToPost(char * midExpression,char * postExpression);
extern void transferToNormal(char* arrayA, char* arrayB);
extern float computor(char *postExpression);
int main() {
	char middleExpression[] = "1-(1+2) *(   3-2)+1";
	cout << "middle expressin : ";
	for (int i = 0; *(middleExpression + i) != '\0'; i++)
		cout << *(middleExpression + i);
	cout << endl;

	char normalMiddle[MAXSIZE];
	transferToNormal(middleExpression,normalMiddle);

	cout << "normal middle expression : ";
	for (int i = 0; *(normalMiddle + i) != '\0'; i++)
		cout << *(normalMiddle + i);
	cout << endl;

	char postfixExpression[MAXSIZE];
	transferMidToPost(normalMiddle,postfixExpression);
	cout << "postfix expressin : ";
	for (int i = 0; *(postfixExpression + i) != '\0'; i++)
		cout << *(postfixExpression + i);
	cout << endl;
	
	cout << "result : " << computor(postfixExpression) << endl;
	
	return 0;
}

   这是main调用的function.cpp源文件,里面包含了那几个函数

using namespace std;
#define MAXSIZE 50
#include<iostream>

struct OperaterPriority {
	char operater;
	int priority;
};

OperaterPriority leftOperPrior[] = { {'=',0},{'(',1},{')',6},
								{'+',3},{'-',3},{'*',5},{'/',5} };
OperaterPriority rightOperPrior[] = { {'=',0},{'(',6},{')',1},
								{'+',2},{'-',2},{'*',4},{'/',4} };
int getLeftPrior(char operater) {
	int i;
	for (i = 0; i < 7; i++)
		if (operater == leftOperPrior[i].operater)
			break;
	return leftOperPrior[i].priority;
}
int getRightPrior(char operater) {
	int i;
	for (i = 0; i < 7; i++)
		if (operater == rightOperPrior[i].operater)
			break;
	return rightOperPrior[i].priority;
}

int comparePrior(char leftOperater,char rightOperater) {
	int i;
	if (getLeftPrior(leftOperater) > getRightPrior(rightOperater))
		i = 1;
	else if (getLeftPrior(leftOperater) == getRightPrior(rightOperater))
		i = 0;
	else if (getLeftPrior(leftOperater) < getRightPrior(rightOperater))
		i = -1;
	return i;
}

//100*900*(23-3)+(9-2)
void transferToNormal(char* arrayA, char* arrayB) {
	char a, aPrior, b, bPrior;
	
	*arrayB = *arrayA;
	arrayA++;
	arrayB++;
//  +-*/的ascii值均小于0   '(' = 40  ')'=41  这俩 小于 +-*/  空格=32
	while (*arrayA != '\0') {
		a = *arrayA; aPrior = *(arrayA - 1);
		b = *arrayB; bPrior = *(arrayB - 1);
		
		if ('0' <= aPrior && aPrior <= '9' && ' ' < a && a < '0') {
			*arrayB = ' ';
			arrayB++;  //从数字到运算符(包括右括号),若紧邻,则加空格,
		}
		else if (' ' < aPrior && aPrior < '0' && '0' <= a && a <= '9') {
			*arrayB = ' ';
			arrayB++;//从运算符(包括左括号)到数字,若紧邻,加空格
		}
		else if (' ' < aPrior && aPrior < '0' && ' ' < a && a < '0') {
			*arrayB = ' ';//从运算符到运算符,包括括号,加空格
			arrayB++;
		}
		else if (aPrior == ' ' && a == ' ')
			while (*arrayA == ' ')
				arrayA++;
		*arrayB = *arrayA;
		arrayA++;
		arrayB++;
	}
	*arrayB = '\0';
}

void transferMidToPost(char* midExpression, char* postExpression) {
	struct SequenceStack {
		char operater[MAXSIZE];
		int  indexTop = -1;
	}sequenceStack;

	sequenceStack.indexTop++;
	sequenceStack.operater[sequenceStack.indexTop] = '=';
	

	char topOperater;
	char* head = midExpression;

	while (*midExpression != '\0')
		if (*midExpression >= '0' && *midExpression <= '9' || 
			*midExpression == ' ' && *(postExpression - 1) != ' ') {
			*postExpression = *midExpression;
			postExpression++;
			midExpression++;
		}
		else if (*midExpression == ' ' && *(postExpression - 1) == ' ')
			midExpression++;
		else {
			topOperater = sequenceStack.operater[sequenceStack.indexTop];
			switch (comparePrior(topOperater, *midExpression)) {
			case -1:
				sequenceStack.indexTop++;
				sequenceStack.operater[sequenceStack.indexTop] =
					*midExpression;
				midExpression++;
				break;
			case 0:     //只有右括号遇到左括号这一种情况
				sequenceStack.indexTop--;
				midExpression++;
				if (*(postExpression - 1) != ' ') {
					*postExpression = ' ';
					postExpression++;
				}  //适当给后缀表达式加空格,运算之间也加空格
				break;
			case 1:
				if (*(postExpression - 1) != ' ') {
					*postExpression = ' ';
					postExpression++;
				}
				*postExpression = sequenceStack.operater[sequenceStack.indexTop];
				
				sequenceStack.indexTop--;
				postExpression++;
			}
		}
	while (sequenceStack.operater[sequenceStack.indexTop] != '=') {
		if (*(postExpression - 1) != ' ') {
			*postExpression = ' ';
			postExpression++;
		}
		*postExpression = sequenceStack.operater[sequenceStack.indexTop];
		sequenceStack.indexTop--;
		postExpression++;
	}
	*postExpression = '\0';
}
float computor(char* postExpression) {
	struct DataStack {
		float data[MAXSIZE];
		int indexTop = -1;
	}dataStack;

	float data,leftData,rightData;
	char c;
	while (*postExpression != '\0') {
		c = *postExpression;
		if (c >= '0' && c <= '9') {
			data = c - '0';
			postExpression++;
			while (*postExpression >= '0' && *postExpression <= '9') {
				data = data * 10 + *postExpression - '0';
				postExpression++;
			}
			dataStack.indexTop++;
			dataStack.data[dataStack.indexTop] = data;
		}
		else if (c == ' ') {}
		else if (c == '+' || c == '-' || c == '*' || c == '/') {
			rightData = dataStack.data[dataStack.indexTop];
			dataStack.indexTop--;
			leftData = dataStack.data[dataStack.indexTop];
			
			switch (c) {
			case '+': 
				dataStack.data[dataStack.indexTop] = leftData + rightData;
				break;
			case '-':
				dataStack.data[dataStack.indexTop] = leftData - rightData;
				break;
			case '*':
				dataStack.data[dataStack.indexTop] = leftData * rightData;
				break;
			case '/':
				if (rightData == 0) {
					cout << "除数为0 " << endl;
					exit(1);
				}
				else {
					dataStack.data[dataStack.indexTop] = 
						(float)leftData / rightData;
					break;
				}
			}
		}
		postExpression++;
	}
	return dataStack.data[dataStack.indexTop];
}

测试结果如下:
在这里插入图片描述
可见结果是正确的。谢谢阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值