Question: Enter a valid expression that contains only add, subtract, subtract and parentheses to get the value of the expression. Dividing means dividing.
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;
}