WaWa Wa's Wonderful Adventures (Second Week Training Autonomous Closure Site)

Keywords: calculator

The Second Weekly Diary

(1) Record of Examples

A-Simple Calculator (Water Problem, Stack Application) HDU-1237

Read in a non-negative integer expression containing only +, -, *, / and calculate the value of the expression.

Input

The test input consists of several test cases, each of which occupies one line and does not exceed 200 characters, separated by a space between integers and operators. There are no illegal expressions. When there is only 0 in a line, the input ends, and the corresponding results are not output.

Output

Output 1 line for each test case, i. e. the value of the expression, to 2 decimal places.

Sample Input

1 + 2
4 + 2 * 5 - 7 / 11
0

Sample Output

3.00
13.36

Understand

	Because the violence simulated the one-time equation, so I didn't feel much when I wrote this question, but because I had to use the stack, I still did some thinking.
	The solution is to store'+'and'-' on the stack and finish the final calculation after completing'*'and'/' first.
	(The idea of this place is still not clever enough. It has a great influence on the calculator that writes the upgraded version the next day. After learning how to transfer suffixes and how to calculate suffixes, I was surprised to find the calculation of suffix expressions.
	Using stack can achieve a very clever level, using stack to solve the "priority" problem.

AC code

#include <bits/stdc++.h>
using namespace std;

int main()  ##  The idea of the code is simple, so no comment is needed.
{	
	string s;
	while(getline(cin,s) && s != "0"){
		int l = s.size();
		stack <double> a;
		stack <char> b;
		double tsum = 0;
		for(int i = 0;i < l;i++){
			if(s[i] >= '0' && s[i] <= '9'){
				tsum = tsum * 10 + s[i] - '0';
			}
			else if(s[i] == '*' || s[i] == '/'){
				char k = s[i];
				double tsum2 = 0;
				for(i = i + 1;s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && i < l;i++){
					if(s[i] >= '0' && s[i] <= '9') tsum2 = tsum2 * 10 + s[i] - '0';
				}
				i--;
				if(k == '/' && tsum2 != 0) tsum /= tsum2;
				else tsum *= tsum2;
			}
			else if(s[i] == '+' || s[i] == '-'){
				a.push(tsum);
				tsum = 0;
				b.push(s[i]);
			}
		}
		a.push(tsum);tsum = 0;
		
		double sum = 0;
		while(!b.empty()){
			double tsum3 = a.top();a.pop();
			char k = b.top();b.pop();
			if(k == '-') tsum3 = -tsum3;
			sum += tsum3;
		}
		sum += a.top();a.pop();
		printf("%.2f\n",sum);
	}
	return 0;
}

But the actual operation of this problem only needs two priorities, and there are a lot of articles to do on the input, so I saw the magic code of the big man.

This is a very powerful way of writing, a very clever idea, which is also used to encapsulate simple calculations later. But after putting more priority levels, I can not complete more difficult problems with this clever idea (high probability is not personal strength), and the inverse Polish expression (suffix expression) is then convenient. Highlighted the role of this type of topic to complete a template killing.
Personally, I think that stack writing (not the ac code of my simple calculator) really provides a good solution for solving the priority of arithmetic problems. Although there is a large amount of code to play the template, it is better than most people can use it after learning (foolish I choose the stack). Later topics will post similar templates.

B-Computation (Inverse Polish Expressions First in the World)

Xiao Ming, with your help, broke the Ferrari's password door and was about to go on. Suddenly, another password door appeared. There was an arithmetic on the door. Among them, only "(")","0-9"," +","-","*","/","is the password. Xiao Ming is not good at maths. He still needs your help. ("/" divides by integers, quotients)

Input

The input consists of one line, which is an arithmetic.

Output

The output is one line, which is the password.

Sample Input

1+(3+2)(7^2+69)/(2)

Sample Output

258

Understand

	At first, I used the idea similar to the one above, encapsulating the calculation function to deal with the arithmetic in (). So, I succeeded in wa. The key point is to deal with multiple (). In the end, I couldn't think about it.
	Come out, after Baidu's suffix expression is converted to suffix expression, I seem to have found the way to Question A, because the calculation of suffix expression only needs a sequential calculation from left to right, and knocked all night.
	Template, the success of the problem a, also has a better way to solve this type of problem.

AC code

#include <bits/stdc++.h>
using namespace std;
map <char,int> p;
  
struct node{
    int num;
    char cmd;
    bool f;
};
  
stack <node> a;
queue <node> b;
  
void change(string s){
    node temp;
    for(int i = 0; i < s.length();i++){
        if(s[i] == '('){
            temp.f = false;
            temp.cmd = s[i];
            a.push(temp);
        }
        else if(s[i] == ')'){
            while (!a.empty() && a.top().cmd != '('){b.push(a.top());a.pop();}
            a.pop();
        }
        else if(s[i] >= '0'&&s[i] <= '9'){
            temp.f = true;
            temp.num = s[i] - '0';
            i++;
            while (i < s.length() && s[i] >= '0'&&s[i] <= '9'){
                temp.num = temp.num * 10 + (s[i] - '0');
                i++;
            }
            i--;
            b.push(temp);
        }
        else{
            temp.f = false;
            while (!a.empty() && p[a.top().cmd]>=p[s[i]]){b.push(a.top());a.pop();}
            temp.cmd = s[i];
            a.push(temp);
        }
    }
    while (!a.empty()){b.push(a.top());a.pop();}
}
  
int cal(){
    stack <node> a1;
    node temp,temp2;
    while(!b.empty()){
        temp = b.front();b.pop();
        if(temp.f == true) a1.push(temp);
        else{
            int nb = a1.top().num;a1.pop();
            int na = a1.top().num;a1.pop();
              
            temp2.f = true;
            if(temp.cmd == '+') temp2.num = na + nb;
            if(temp.cmd == '-') temp2.num = na - nb;
            if(temp.cmd == '*') temp2.num = na * nb;
            if(temp.cmd == '/') temp2.num = na / nb;
            if(temp.cmd == '^') temp2.num = pow(na,nb);
              
            a1.push(temp2);
        }
    }
    return a1.top().num;
}
  
int main()
{
    p['+'] = p['-'] = 1;
    p['*'] = p['/'] = 2;
    p['^'] = 3;
    string s;
    cin >> s;
    change(s);
//  while(!b.empty()){
//      node temp = b.front();
//      if(temp.f == true) cout << temp.num << ' ';
//      else cout << temp.cmd << ' ';
//      b.pop();
//  }
    int ans = cal();
    cout << ans << endl;
    return 0;
}

Later the next day when I was thinking about it, I felt that the calculation of suffixes was essentially a split of suffix expressions calculated by stack according to priority, and then I changed the following code.

#include <bits/stdc++.h>
using namespace std;
map <char,int> p;
 
stack <int> a;
stack <char> b;
  
int cal(char k){
    int nb = a.top();a.pop();
    int na = a.top();a.pop();
            
    if(k == '+') return na + nb;
    if(k == '-') return na - nb;
    if(k == '*') return na * nb;
    if(k == '/') return na / nb;
    if(k == '^') return pow(na,nb);
}
 
void change(string s){
    for(int i = 0; i < s.length();i++){
        if(s[i] == '(') {b.push(s[i]);}
        else if(s[i] == ')'){
            while (!b.empty() && b.top() != '('){
                int temp = cal(b.top());
                a.push(temp);
                b.pop();
            }
            b.pop();
        }
        else if(s[i] >= '0'&&s[i] <= '9'){
            int temp = s[i] - '0';
            i++;
            while (i < s.length() && s[i] >= '0'&&s[i] <= '9'){
                temp = temp * 10 + (s[i] - '0');
                i++;
            }
            i--;
            a.push(temp);
        }
        else{
            while (!b.empty() && p[b.top()]>=p[s[i]]){
                int temp = cal(b.top());
                a.push(temp);
                b.pop();
            }
            b.push(s[i]);
        }
    }
    while (!b.empty()){
        int temp = cal(b.top());
            a.push(temp);
            b.pop();
    }
}
  
int main()
{
    p['('] = 1;
    p['+'] = p['-'] = 2;
    p['*'] = p['/'] = 3;
    p['^'] = 4;
    string s;
    cin >> s;
    change(s);
    cout << a.top() << endl;
    return 0;
}

Reference Big Boy blog
Interfix to suffix https://blog.csdn.net/coder_dacyuan/article/details/79941743
Computation of suffixes https://blog.csdn.net/sjhdxpz/article/details/81210448

Posted by danielleuk on Sun, 04 Aug 2019 04:49:25 -0700