# Implementation of simple calculator in computer software technology practice

## Implementation of simple calculator in computer software technology practice

Test requirements:

1. Learn the design of graphical interface, use MFC application (Java swing or QT framework, or C#) to create dialog based application, and add buttons, edit boxes and other controls;
2. It can input and realize simple arithmetic operation through the designed button control. The expression is required to be displayed in the edit box, and the operation result can be output and displayed in the edit box; And save the historical expression operation record.
3. It can also solve the arithmetic expression of mixed operation. The arithmetic expression includes addition, subtraction, multiplication, division, parentheses and other operators; And can identify parentheses, and the priority is correct.
Experiment preparation:
1.1 arithmetic expression evaluation: the data (i.e. operands) involved in the operation can be integers or real numbers, and the operators (i.e. operators) are binary operators such as +, -, / (addition, subtraction, multiplication and division), including parentheses;
For example: 56 + 10-25 = 15
6+(5-4/2)*3=15
Operation rules:
Multiply and divide first, then add and subtract, and calculate from left to right, first in parentheses and then out of parentheses;
Three representation features of expressions:
1) The relative order between operands remains unchanged;
2) The relative order of operators is different;
3) The priority of the operator has been considered in the suffix expression. There are no parentheses, only operands and operators.
The method I used this time is: Method 2: double stack operator priority method.
Double stack operator priority method in order to realize expression evaluation, two stacks need to be set:
One is the operator stack OP, which is used to register operators;
The other is called operand stack OPND, which is used to register operands and operation results.
The key of the algorithm is to judge the priority of operators.
If the priority of the operator is high, it is directly put into the OP stack. If the priority is low, the two operands at the top of the OPND stack need to be extracted for operation, and then the result is put into the stack again. When encountering the right bracket, all operands from the OP stack to the left bracket need to be operated, and then save the result to the stack.
The core idea is like this. The specific algorithm is as follows: (I have annotated the core idea in most C + + languages)
Comparison priority function:
```int priority(int state, char a){
int rank;
switch (a) {
case '+':
case '-':
rank = 1;//+, - priority is 1.
break;
case '*':
case '/':
rank = 2;//*, / priority is 2.
break;
case '(':// Ensure that "(" is directly put on the stack and will not interfere with the judgment of other operators.
if (state == 0)
rank = 3;
else
rank = 0;
break;
case '#':
rank = 0;//#Indicates the end.
break;
default:
break;
}
return rank;
}//The priority function is mainly used to judge the priority of operators in the stack.
```

Calculation expression function:

```double calculate(char op, double num1, double num2)
{
double anwser;
switch (op) {
case '+':
anwser = num1 + num2;
break;
case '-':
anwser = num1 - num2;
break;
case '*':
anwser = num1 * num2;
break;
case '/':
anwser = num1 / num2;
break;
default:
break;
}
return anwser;
}//The calculate function mainly realizes the operation of two numbers (including addition, subtraction, multiplication and division), and uses OP to read the operators in the op stack.
```
```The function that reads the expression and calculates the result:
```
``````cpp

```cpp
double result(string s,int a,int &sign) {
stack<char> OP;//Define OP stack to store operation operators.
stack<double> OPND;//Define OPND to store the numbers to be calculated (including decimals).
OP.push('#');// First, put a stop operator in the stack of operators.
OPND.push(0);
string num;//Used to save a complete arithmetic number.
for (int i = 0; i<a; i++) {//Read the entire s string.
if ((s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') && (s[i + 1] == '+' || s[i + 1] == '-' || s[i + 1] == '*' || s[i + 1] == '/'))
{
sign = 0;
break;
}
if (s[i] == '/' && s[i + 1] == '0')
{
sign = 0;
}
if (isdigit(s[i])) {//Judge whether it is a number from 0 to 9.
while (isdigit(s[i]) || s[i] == '.') {
num.push_back(s[i]);//Judge to add a decimal point at the end after entering the decimal point.
i++;//Continue to move back one digit and read in the part after the decimal point.
}
double a = atof(num.c_str());//Convert the whole digital string read out above into a double precision number and assign it to a.
OPND.push(a);// Put the number a into the stack of OPND.
num.clear();//Clear the number in num.
i--;//Move back one bit.
}
else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == '(') {
if (s[i] == '(') {
if (s[i + 1] == '-')
OPND.push(0);
};
if (priority(0, s[i]) > priority(1, OP.top()))//Compare the operator priority in the string s with the priority in the OP stack. If it is larger, it will be put on the stack.
OP.push(s[i]);
else {
while (priority(0, s[i]) <= priority(1, OP.top())) {
char temp = OP.top();//Define the temp save OP stack top operator.
OP.pop();//Pop stack top
double op2 = OPND.top();//Assign the number at the top of OPND stack to op2 (due to the first in, last out principle, it must be assigned to op2 to ensure the operation order).
OPND.pop();//Pop stack top
double op1 = OPND.top();//Take out the number at the top of the current stack of OPND and carry out the next operation.
OPND.pop(); //Pop stack top
OPND.push(calculate(temp, op1, op2));//Stack the calculation results.
}
OP.push(s[i]);
}
}
else if (s[i] == ')') {
while (OP.top() != '(') {//Take out operation until "(" in the OP stack will be taken out.
char temp = OP.top();
OP.pop();
double op2 = OPND.top();
OPND.pop();
double op1 = OPND.top();
OPND.pop();
OPND.push(calculate(temp, op1, op2));
}
OP.pop();//")" pops up and ends.
}//The priority has been determined in the above operation, so the numbers in brackets can be calculated directly without repeated judgment.
}
while (OP.top() != '#') {
char temp = OP.top();
OP.pop();
double op2 = OPND.top();
OPND.pop();
double op1 = OPND.top();
OPND.pop();
OPND.push(calculate(temp, op1, op2));
}//Take out all the operators in the stack, calculate all the expressions, and put the value back into the OPND stack again.
return OPND.top();
;//At this time, the result at the top of the OPND stack is the result of the whole expression.
}
```

`
You need to judge whether it meets the specification of the expression, and make the output result have decimal output double type and no decimal output int type. So I set a sign identifier to identify whether the whole expression meets the standard. If sign is 1; If the sign is 0, the input expression is incorrect. The specific implementation is as follows:

```int main(){
double b;
string s;
int a,SIGN=1;//The flag bit is set to 1 first
cin>>s;
a=s.length();
b=result(s,a,SIGN);
if(SIGN==1)
cout<<b<<endl;
if(SIGN==0)//If the judgment condition does not meet the correct expression, the flag will be set to 0