201903-2 24:00

preface

This is a problem of expression evaluation, and it is still a simple type. The teacher gave us such an assignment last semester, which is a little more difficult than this problem. However, when I do it, I can't distinguish the priority of the four operators, and I'm always confused. Therefore, I think it is necessary for me to write this question.

Title (with test sample)

The title link is attached: Twenty four

Here is also a screenshot of the topic:

Test sample

10
9+3+4x3
5+4x5x5
7-9-9+8
5x6/5x4
3+5+7+9
1x1+9-9
1x9-5/9
8/5+6x9
6x7-3x6
6x4+4/5

thinking

This topic is done with a stack. My approach is to build a number stack and a symbol stack. Then let me talk about my ideas

First, we get a string, so how do we calculate it? Then it must be converted! The numeric characters will be converted to our numeric type, and the symbolic characters will be converted to the operator type we can operate. This should be needless to say. So, let's take a look at how we do our calculations?

Let's recall, did we have a priority when we learned addition, subtraction, multiplication and division as children? For example, multiply and divide first, then add and subtract, and the same level operation is carried out from left to right·······

OK, we only have four operations. These two rules are enough.

We first read in the string, and then analyze it. If it is a number, it will be pressed into the number stack, and if it is a symbol, it will be pressed into the symbol stack. However, what should we pay attention to when pressing symbols? Yes, pay attention to its priority. If the priority of the current character is lower than that of the top element of the stack, do I have to finish the previous operation before pressing the symbol? Why?

For example, 2 * 3 + 1. At this time, we judge whether + should be pushed into the stack. Obviously, we can't, because if it is pushed into the stack, will we calculate 3 + 1 first? Then this is not our correct algorithm. Our rule is to multiply and divide first, then add and subtract, and the same level operation is carried out from left to right. That is to say, even at the same level, the characters pressed in front of us have higher priority than the characters pressed in behind you, so if the characters behind you want to be pressed in, you can enter the stack after my previous operation.

Well, in this way, we can complete a priority table, which should have more symbols. I'm just here to understand this problem, and only give the following four kinds. When I have time, I'll write the evaluation content of the expression, and then complete them.

a\b + - * /
+ > > < <
- > > < <
* > > > >
/ > > > >

a in the table represents the symbol at the top of the stack, and b represents the symbol to be pressed currently

In this way, when we observe the table, we will know that only when the symbol to be pressed is * or / can it be directly pressed in, otherwise some symbols in it must be popped up for calculation before being pressed in. This is a good rule to help us reduce the amount of code.

OK, now that the analysis is here, I think we can start writing code. There are corresponding comments in the code. Friends who don't understand can have a look at the code.

code

/* Twenty four */
#include <bits/stdc++.h>
using namespace std;
/* Arithmetic operation */
int operate(int a, char b, int c) {
    if (b == '+') return a + c;
    if (b == '-') return a - c;
    if (b == 'x') return a * c;
    if (b == '/') return a / c;
}

int n;
int main() {
    cin >> n;
    stack<int> a;
    stack<char> b;
    while (n--) {
        string str;
        cin >> str;
        int len = str.length();
        for (int i = 0; i < len; i++) {
            if (isdigit(str[i])) {                                    //If it is a number, press it into the number stack
                a.push(str[i] - '0');
            } else {
                if (b.empty())       //If the character stack is empty, press the stack directly
                    b.push(str[i]);
                else if ((b.top() == '+' || b.top() == '-') &&        //If it is a character, judge the priority. If it is a special case, press the stack directly
                         (str[i] == 'x' || str[i] == '/')) {
                    b.push(str[i]);

                } else {                                              //Otherwise, calculate the previous value first
                    int num2 = a.top();
                    a.pop();
                    int num1 = a.top();
                    a.pop();
                    char c = b.top();
                    b.pop();
                    int num = operate(num1, c, num2);
                    a.push(num);
                    b.push(str[i]);
                }
            }
        }
        while (!b.empty()) {                                      //Take out all the symbols in the stack for calculation
            int num2 = a.top();
            a.pop();
            int num1 = a.top();
            a.pop();
            char c = b.top();
            b.pop();
            int num = operate(num1, c, num2);
            a.push(num);
        }
        if (a.top() == 24)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
        a.pop();
    }
    return 0;
}

Write at the end

The expression evaluation of this question is still a very simple form. It is recommended that you take all symbols into account, such as brackets. Bloggers will not write it because of limited time (there will be an exam tomorrow, May 5). If you have time later, you can add the content of expression evaluation. OK, that's it. Thank you for reading.

Tags: CCF

Posted on Sun, 05 Dec 2021 03:26:39 -0500 by EvilPrimate