中缀表达式

不含括号的中缀表达式

代码实现

//直接计算中缀表达式
//不含括号
#include<iostream>
#include<stack>
#include<string>

using namespace std;

//运算符号优先级比较
//加减为低级运算,乘除是高级运算;先算乘除
//return 1 means can calculate, else can not.
int getPriority( stack<char> operators )
{
	if( !operators.empty()  && ( operators.top() == '*' || operators.top() == '/') ){
		return 1;
	}

	return 0;
}


//输入操作符栈 和 操作数栈 进行计算
void calculate(stack<double> &operands, stack<char> &operators)
{
	double op1, op2, res;
	char operation;

	op2 = operands.top();
	operands.pop();
	op1 = operands.top();
	operands.pop();

	operation = operators.top();
	operators.pop();

	switch( operation ){
		case '+':
			res = op1 + op2;
			break;
		case '-':
			res = op1 - op2;	//对顺序有要求
			break;
		case '*':
			res = op1 * op2;
			break;
		case '/':
			res = op1 / op2;	//这个顺序不能反
			break;
	
	}

	//cout << op1 << operation << op2 << "=" << res << endl;	//test
	operands.push(res);

}


int main()
{
	stack<double> operands;	//除法运算可能会出现小数
	stack<char> operators;

	string formula;
	string number;

	const string numbers = "0123456789";
	const string operation = "+-*/";

	cin >> formula;
	for( string::iterator c = formula.begin();  c != formula.end();  c++ ){

		//处理数字
		if( numbers.find(*c) != string::npos ){
			while( numbers.find(*c) != string::npos ){
				number += *c;
				c++;
			} 
			operands.push( stod(number) );
			number.clear();

		       //读完最后一个数字
			if ( c == formula.end() ){
				if( getPriority(operators) == 1 ){	//最后一个操作符可能是乘除
					calculate(operands, operators);
				}
				break;	
			}
		}

		//calculate, 先算乘除
		if( operation.find(*c) != string::npos ){
			if ( getPriority(operators)  ==  1 ){
				calculate( operands, operators );
			}
			operators.push((*c));
		}
	}


	//处理剩余的加减
	while( !operators.empty() ){
		char operation = operators.top();

		//减法有顺序要求;1-2+3,先执行1-2=-1,再执行-1+3
		if( operation == '+' ){
			operators.pop();
			if( !operators.empty()  &&  operators.top() == '-' ){
				double tmp = operands.top();
				operands.pop();

				calculate( operands, operators );

				operators.push(operation);
				operands.push(tmp);
			}	
			else{
				operators.push(operation);
				calculate( operands, operators );
			}

		}
		else{
			calculate( operands, operators );
		}

	}
	
	cout << formula << " = " << operands.top() << endl;
	return 0;
}

含括号的中缀表达式代码实现

//直接计算中缀表达式
//含括号
#include<iostream>
#include<deque>
#include<string>

using namespace std;


//运算符号优先级比较
//return 1 means can calculator, else can not.
int getPriority( deque<char> operators )
{
	if( !operators.empty()  && ( operators.back() == '*' || operators.back() == '/') ){
		return 1;
	}

	return 0;
}


double calculate( double op1, double op2, char operation )
{
	double res;

	switch( operation ){
		case '+':
			res = op1 + op2;
			break;
		case '-':
			res = op1 - op2;	//对顺序有要求
			break;
		case '*':
			res = op1 * op2;
			break;
		case '/':
			res = op1 / op2;	//这个顺序不能反
			break;
	}

	//cout << op1 << operation << op2 << "=" << res << endl;	//test

	return res;
}

void calculator(deque<double> &operands, deque<char> &operators)
{
	double op1, op2, res;
	char operation;

	operation = operators.back();
	operators.pop_back();

	//这个糟糕的顺序
	if( operation == '-' ){
		op1 = operands.back();
		operands.pop_back();
		op2 = operands.back();
		operands.pop_back();
	}else{
		op2 = operands.back();
		operands.pop_back();
		op1 = operands.back();
		operands.pop_back();
	}


	res = calculate( op1, op2, operation );

	operands.push_back(res);
}




int main()
{
	deque<double> operands;	//除法运算可能会出现小数; 使用deque,比栈更灵活
	deque<char> operators;

	string formula;
	string number;

	const string numbers = "0123456789";
	const string Operation = "+-*/";

	cin >> formula;
	for( string::iterator c = formula.begin();  c != formula.end();  c++ ){

		//处理数字
		if( numbers.find(*c) != string::npos ){
			while( numbers.find(*c) != string::npos ){
				number += *c;
				c++;
			} 
			operands.push_back( stod(number) );
			number.clear();

		       //读完最后一个数字
			if ( c == formula.end() ){
				if( getPriority(operators) == 1 ){	//最后一个可能是乘除
					calculator(operands, operators);
				}
				break;	
			}
		}

		//处理 + - * /
		if( Operation.find(*c) != string::npos ){
			//calculator, 先算乘除
			if ( getPriority(operators)  ==  1 ){
				calculator( operands, operators );
			}
			operators.push_back((*c));
		}
		//处理括号
		else{
			if( *c == '(' ){
				operators.push_back((*c));
			}
			//遇到)”时,算出()内算式的值
			else{	
				//)前面可能是乘除
				if(  getPriority(operators) == 1 ){
					calculator(operands, operators);
				}

				//此时括号内已经没有乘除
				deque<double> tmp_oprands;
				deque<char> tmp_operators;
				//把()内的算式pop到新的栈
				while( operators.back() != '(' ){
					tmp_oprands.push_back(operands.back());
					operands.pop_back();
					
					tmp_operators.push_back(operators.back());
					operators.pop_back();
				}
				tmp_oprands.push_back(operands.back());
				operands.pop_back();
				operators.pop_back();	//弹出“(”
				
				while(!tmp_operators.empty()){	//计算括号内的算式
					calculator( tmp_oprands, tmp_operators );
				}

				operands.push_back( tmp_oprands.back() );	//push结果
				tmp_oprands.pop_back();

			}
		
		}
	}


	//处理剩余的加减
	double op1, op2, res;
	char operation;
	while( !operators.empty() ){

		//因为前面使用的是deque结构而不是stack,所以这里可以从栈底开始读取
		//(考虑到减法运算过程中的y顺序要求)
		op1 = operands.front();
		operands.pop_front();
		op2 = operands.front();
		operands.pop_front();

		operation = operators.front();
		operators.pop_front();

		res = calculate( op1, op2, operation);

		operands.push_front(res);
	}
	
	cout << formula << " = " << operands.back() << endl;
	return 0;
}

改进

前面的算法将加减与乘除分开处理,导致后面运算加减的时候还要考虑减法的运算顺序问题,变得麻烦了。
下面是改进后的代码

#include<iostream>
#include<string>
#include<stack>

using namespace std;


//return the answer of op1 operation op2
double calculate( double op1, double op2, char operation )
{
	double res;

	switch(operation){
		case '-':
			res = op1 - op2;
			break;
		case '+':
			res = op1 + op2;
			break;
		case '*':
			res = op1 * op2;
			break;
		case '/':
			res = op1 / op2;
			break;
	}
	
	cout << op1 << operation << op2 << " = " << res << endl;	//test
	return res;
}


int getPriority( char operation )
{
	//这个优先级很微妙
	if ( operation == '(' )
		return 1;
	else if( operation == '+' ||  operation == '-' )
		return 2;
	else if( operation == '*' ||  operation == '/' )
		return 3;
}

void calculator( stack<double> &operands,  stack<char> &operators )
{
	double op1, op2, ans;
	char operation;

	op2 = operands.top();
	operands.pop();
	op1 = operands.top();
	operands.pop();

	operation = operators.top();
	operators.pop();

	ans = calculate( op1, op2, operation );

	operands.push(ans);
}


//(1+2)*33-8/2-9

int main()
{
	const string Numbers = "0123456789";
	const string Operators = "+-*/";

	stack<double> operands;
	stack<char> operators;

	string formula;

	cin >> formula;

	for( string::iterator c = formula.begin(); c != formula.end();  c++ ){
	

		//字符转数字
		if( Numbers.find(*c) != string::npos ){
			string num;
			while( c != formula.end()  &&   Numbers.find(*c) != string::npos ){
				num += *c;
				c++;
			}
			c--;	//退一步
			operands.push( stod(num) );
			//cout << operands.top() << endl;	//test
		}
		//运算
		else if( Operators.find(*c) != string::npos ){
			if( operators.empty() )	
				operators.push(*c);
			else{
				//这里while很关键
				while( !operators.empty()  &&  getPriority(operators.top()) >= getPriority(*c) ){
					calculator( operands, operators);
				}
				operators.push(*c);
			}
		}
		//括号处理
		else{
			if( *c == '(' )
				operators.push(*c);
			else{
				while( operators.top() != '(' ){
					calculator( operands, operators);
				}
				operators.pop();
			}
		}
	}


	while( !operators.empty() ){
		calculator( operands, operators );
	}

	cout << formula << " = " << operands.top() << endl;
	return 0;
}
原文地址:https://www.cnblogs.com/friedCoder/p/12260630.html