C++ 后缀表达式转为中缀表达式,并计算结果

2、输入表达式,输出值。分两种情况:中缀表达式和后缀表达式。

中缀表达式求值:先将中缀表达式建立二叉树转后缀表达式,然后再求值。

尝试1:

#include 
#include 
#include 
#include //sum1=atof(t1.c_str());
using namespace std;
 

//后缀表达式求值,这种方式的弊端很明显,只能计算单个位置的数据,不能出现多位数和小数,原因是我这里每次取数是expression[i]造成的 
double  postfix_expression(string expression){
	//56+2*3+
	double stack[20];//操作数栈
	int top = -1;//栈顶指针
	for(int i=0;i>ex;
	//用例:3*(5+4)/8+4*(5+2) 
    cout<

猜想,我们对数字的判断应该在之前就判断完毕,因为后缀表达式中,如:54+3*8/52+4*+,是比较难确定54还是5 4 当然可以用操作符的个数匹配,但是比较麻烦。这里,我们可以用中缀表达式,也就是原来输入的数据表达式,然后我们截取数据放入集合中,集合的类型是vector,我们在使用后缀表达式的时候,转换数据就会比较方便。下面关键是如何处理由中缀表达式向后缀表达式转化。

参考数据结构:

需要用操作符的优先级进行栈运算。用icp(in coming priority)表示当前扫描到的运算符的优先级,用isp(in stack priority)表示该运算符进栈后的优先级。

操作符

#

(

* /

+ -

)

isp

0

1

5

3

6

icp

0

6

4

2

1

 

举例说明:3*(5+4)/8+4*(5+2)

中缀表达式:3*(5+4)/8+4*(5+2)  后缀表达式:354+*8/452+*+

步骤

扫描项

项类型

动作

字符栈内内容

输出

0

 

 

‘#’进栈,读取下一字符

#

 

1

3

操作数

直接输出

#

3

2

*

操作符

isp(#)

#*

 

3

(

操作符

isp(*)

#*(

 

4

5

操作数

直接输出

#*(

5

5

+

操作符

isp(()

#*(+

 

6

4

操作数

直接输出

 

4

7

)

操作符

isp(+)>icp()),出栈

#*(

+

 

 

 

isp(()==icp()),退栈

#*

 

8

/

操作符

isp(*)>icp(/),出栈

#

*

 

 

 

isp(#)

#/

 

9

8

操作数

直接输出

 

8

10

+

操作符

isp(/)>icp(+),出栈

#

/

11

 

 

isp(#)

#+

 

12

4

操作数

直接输出

 

4

13

*

操作符

isp(+)

#+*

 

14

(

操作符

isp(*)

#+*(

 

15

5

操作数

直接输出

 

5

16

+

操作符

isp(()

#+*(+

 

17

2

操作数

直接输出

 

2

18

)

操作符

isp(+)>icp()),出栈

#+*(

+

 

 

 

isp(()==icp()),退栈

#+*

 

19

#

操作符

isp(*)>icp(#),出栈

#+

*

 

 

 

isp(+)>icp(#),出栈

#

+

 

 

 

isp(#)==icp(#),退栈结束

#)

 

就可以得到中缀表达式,所以这里需要使用优先级比较+栈

#include 
#include 
#include 
#include 
#include //sum1=atof(t1.c_str());
using namespace std;
 
/*
操作符	#	(	* /	 + -	)
isp	   0	1	5	 3 	   6
icp	   0	6	4	 2 	   1
*/
//四则运算,栈内>入栈,而且*/一定高于+-;括号,栈内<入栈, 站内尾大,入栈头大,占两端 
// 前期思考数据封装函数,最后演化成 transform_postfix 中的中心架构 
vector data_package(string expression){
	vector vc;
	int index=0, count=0;//记录需要截取字符串的下标位置
	for(int i=0;i
	vector vc = data_package(expression);
	char op_stack[20];//+-*/():335516   224461
	int top = -1;
	top++;
	op_stack[top]='#';
	string str="";
	int index=0, count=0;//记录需要截取字符串的下标位置
	int i=0;
	while(top!=-1){
		if(i==expression.length()){
			expression.append("#");//因为栈可能没出完,而表达式判断已经到了末尾 
		}
		if(expression[i]=='+' or expression[i]=='-' or expression[i]=='*' or expression[i]=='/' or expression[i]==')' or expression[i]=='#' or expression[i]=='('){
			//数字在前 
			if(count!=0){
				string s=expression.substr(index, count);
				str.append(s);
				str.append(" ");  //数字,直接输出 
			}
			index=i+1;
			count=0;
			
			//符号判断在后 
			//isp icp 大,进;小,顶出;等,退 
			if(get_isp(op_stack[top])get_icp(expression[i])){
				bool flag = true;//是否循环 
				while(flag){//使用标识,进栈或者退栈,就退出循环 
					if(get_isp(op_stack[top])>get_icp(expression[i])){
						//小 ,顶出
						str.append(transform_op_stack_to_string(op_stack[top])+" ");
						//这里之所以要把char 转为 string ,是因为使用char 数组,加入的是该地址后的所有的字符 
					//	cout<>expression;
	//用例:3*(5+4)/8+4*(5+2) 
	string postfix = transform_postfix(expression);//后缀表达式:354+*8/452+*+ 
	double result = postfix_expression_fix(postfix);
    cout<<"表达式:"<

C++ 后缀表达式转为中缀表达式,并计算结果_第1张图片

下面是使用电脑计算器计算的结果: 

C++ 后缀表达式转为中缀表达式,并计算结果_第2张图片

 

 

 

作者: 无涯明月

上篇: C++ STL deque(双向队列)

你可能感兴趣的:(C++,数据结构,数据结构习题刷题)