Expression evaluation (recursion and stack)

Question: Enter a valid expression that contains only add, subtract, subtract and parentheses to get the value of the expression. Dividing means dividing.

Input format
Enter a line containing an expression.
Output format
Output the value of this expression.
sample input
1-2+3*(4-5)
sample output
-4
Data size and conventions
The expression length is not more than 100, the expression operation is legal and the operation process is carried out in int.

1. Recursively:


#include<iostream>
#include<cctype>
using namespace std; 

int expression();//Expression 
int term();//term 
int factor();//factor 

int main()
{
	cout << expression() <<endl;
	return 0;
}

int expression()
{
	int result = term();
	char c = cin.peek();
	while(c == '+' || c == '-')
	{
		cin.get();
		if(c == '+')
		result += term();
		else if(c == '-')
		result -= term();
		c = cin.peek();
	}
	return result;
}

int term()
{
	int result = factor();
	char c = cin.peek();
	while(c == '*' || c == '/')
	{
		cin.get();
		if(c == '*')
		result *= factor();
		if(c == '/')
		result /= factor();
		c = cin.peek();
	}
	return result;
}

int factor()
{
	int result = 0;
	char c = cin.peek();
	if(c == '(')
	{
		cin.get();
		result += expression();
		cin.get();
	}
	else while(isdigit(c))
	{
		cin.get();
		result = result * 10 + c - '0';
		c = cin.peek();
	}
	
	return result;
}


2. Using stack

(1): First, set the operand stack as empty stack, and set the operator stack as the bottom element of the stack'#'(with the lowest priority).

(2): Priorities are compared by setting values for in-stack and out-of-stack operators

(3): Find all operators and operands in the expression in turn. For the operands directly into the stack, compare the priority between the operator and the top operation of the operator stack. If the priority in the stack is high, then carry out the corresponding operation and the operands and the operators in the stack are all out of the stack. If the priority is equal, only the operators in the stack need to go out of the stack to find the next operator, if the stack is excellent. If the first level is low, the out-of-stack operators are put on the stack. Loop in turn until all the operators and operands in the expression have been analyzed.

(4): Finally, there will be only one element left in the operand stack, and that element will also be the value of the expression being evaluated.



#include<iostream>
#include<stack>
#include<string>
#include<cstdlib>
using namespace std;

/*Judging the Priority Relation Function between Symbols
*1 Representation >, 0 = and - 1<
*c1 Operator in stack, operator out of c2 stack
*/
int Judge(char c1,char c2)
{
	int a1,a2;
	if('+'==c1||'-'==c1) a1 = 3;
	if('*'==c1||'/'==c1)a1 = 5;
	if('('==c1) a1 = 1;
	if(')'==c1) a1 = 7;
	if('#'==c1) a1 = 0;

	if('+'==c2||'-'==c2)a2 = 2;
	if('*'==c2||'/'==c2)a2 = 4;
	if('('==c2) a2 = 6;
	if(')'==c2) a2 = 1;
	if('#'==c2) a2 = 0;
	if(a1>a2) return 1;
	if(a1==a2) return 0;  //Only (), # can be equal. 
	if(a1<a2) return -1;
}
//Symbolic Operational Function
double run(char c ,double d1,double d2)
{
	switch (c)
	{
	case '+':
		return d1+d2;
		break;
	case '-':
		return d1-d2;
		break;
	case'*' :
		return d1*d2;
		break;
	case '/':
		return d1/d2;
		break;
	default:
		return 0.0;
		break;
	}
}
int main()
{
	char op[9] = "+-*/()#";
	string str ;
	cin>>str;
	//Add an'#'end identifier to the expression string str
	str.append(1,'#'); //String & append (int n, char c): Add n characters C at the end of the current string
	stack<char> OPTR;//Operator stack
	stack<double> OPND;//Operand stack
	int a = -1;
	//First put the # symbol on the stack
	OPTR.push('#');
	while(true)
	{
	 int b = a+1;
	 a = str.find_first_of(op,a+1);//s. find_first_of (letter, pos). This means to search for characters in the first letter in s and start searching from POS.
	 if(a==string::npos) break; //npos is a constant used to denote positions that do not exist
	 if(a!=b)
	 {
	 string ss(str,b,a-b);
	 double d=atof(ss.c_str());//atof() scans the parameter nptr string, skips the space character in front of it, does not start the conversion until it encounters a number or a positive or negative symbol, and then ends the conversion when it encounters a non-numeric or string knot // bundle ('\ 0') and returns the result; converts the string to a floating-point number
	 //Data First Stack
	 OPND.push(d);
	 }
	 //Operator priority comparison
	 int ju = Judge(OPTR.top(),str[a]);
	 if(-1==ju)//High Out-of-stack Priority Direct Stack
	 {
	     OPTR.push(str[a]);
	 }
	 if(0==ju)//Rear parentheses encounter front parentheses and go directly out of the stack 
	 {
		 OPTR.pop();
	 }
	 if(1==ju)//High priority in stack and operation out of stack
	 {
		 double d1 = OPND.top();
		 OPND.pop();
		 double d2 = OPND.top();
		 OPND.pop();
		 d1 = run(OPTR.top(),d2,d1);
		 //Operation results are stacked
		 OPND.push(d1);
		 OPTR.pop();
		 a--;  //Subscription of an expression 
	 }
	}
	//Delete the'#'end identifier at the end of the expression
	str.erase(str.length()-1,1);
	cout<<OPND.top()<<endl;
}





Posted by epilator on Mon, 15 Apr 2019 09:15:31 -0700