[Question of the day] Acwing 3302. Expression evaluation

topic

Given an expression, where the operator only contains +, -, *, / (addition, subtraction, multiplication, and division), and possibly parentheses, please find the final value of the expression.

note:

The data guarantees that the given expression is legal.
The title guarantee symbol-only appears as a minus sign, not as a minus sign. For example, expressions such as -1+2,(2+2)*(-(1+1)+2) will not appear.
The title guarantees that all numbers in the expression are positive integers.
The title guarantees that the expression does not exceed 231-1 in the intermediate calculation process and the result.
The division in the question refers to rounding to 0, which means that the result greater than 0 is rounded down, such as 5/3=1, and the result less than 0 is rounded up, such as 5/(1−4)=−1 .
Divide in C++ and Java is rounded to zero by default; Divide in Python // is rounded down by default, so the divisor in Python's eval() function is also rounded down, which cannot be used directly in this question.
The input format is
one line, which is a given expression.

The output format is
one line, which is the result of the expression.

Data range
The length of the expression does not exceed 105.

Input sample:
(2+2)*(1+1)
Output sample:
8

Ideas

First convert the prefix expression to a postfix expression

  1. If it is a number, output directly
  2. If it is an operator, if the top element of the stack is also an operator and the priority of the current operator is less than that of the top operator and the stack is not empty, pop the top element of the stack and output. Push the current operator onto the stack.
  3. If the current element is right expansion:
    1. If the stack is not empty, pop the stack and output until it encounters the left parenthesis
    2. Finally, if the stack is not empty, pop the left wide number
  4. If it is a left wide number, directly push the stack
  5. The remaining elements in the output stack
    // 变为后缀表达式
    for (auto iter = expression.begin(); iter != expression.end(); iter++)
    {
    
    
		// 如果是数字,直接输出
    	if (*iter >= '0' && *iter <= '9')
    	{
    
    
    		while (*iter >= '0' && *iter <= '9' && iter != expression.end())
    		{
    
    
    			p_expression.push_back(*iter);
    			iter++;
    		}
    		iter--;
    		p_expression.push_back(' ');
    	}
    	// 如果是运算符,若栈顶元素也是运算符且当前运算符优先级小于栈顶运算符且栈不为空,弹出栈顶元素并输出
    	// 将当前运算符压栈
    	else if (isp(*iter))
        {
    
    
            while ( !s1.empty() && (rankp(*iter) <= rankp(s1.top())) && isp(s1.top()) )
            {
    
    
                p_expression.push_back(s1.top());
                s1.pop();
            }
            s1.push(*iter);
        }
        // 如果当前元素是右扩号:
        // 如果栈不为空,一直弹栈并输出直到遇到左括号
        // 最后若栈不为空,弹出左阔号
        else if (*iter == ')')
        {
    
    
            while (!s1.empty() && s1.top() != '(')
            {
    
    
                p_expression.push_back(s1.top());
                s1.pop();
            }
            
            if (!s1.empty())
                s1.pop();
        }
        // 如果是左阔号,直接压栈
        else if (*iter == '(')
        {
    
    
            s1.push(*iter);
        }
    }
    // 最后输出栈中剩余元素
    while (!s1.empty())
    {
    
    
        p_expression.push_back(s1.top());
        s1.pop();
    }

Calculate the value of the postfix expression

  1. If it is a number, directly push the stack
  2. If it is an operator, pop up two numbers, perform a left operation with the current operator, and push the result onto the stack
    for (auto iter = p_expression.begin(); iter != p_expression.end(); iter++)
    {
    
    
    	t = "";
        while (*iter >= '0' && *iter <= '9')
        {
    
    
        	t.push_back(*iter++);
        }

        if (t != "")
        	s2.push(atoi(t.c_str()));

        if (*iter != ' ')
        {
    
    
			int num1 = s2.top();
			s2.pop();
			int num2 = s2.top();
			s2.pop();


            if (*iter == '+')
                temp = num2 + num1;
            if (*iter == '-')
                temp = num2 - num1;
            if (*iter == '*')
                temp = num2 * num1;
            if (*iter == '/')
                temp = num2 / num1;
            s2.push(temp);
        }
    }
    if (!s2.empty())
		cout << s2.top();

Guess you like

Origin blog.csdn.net/qq_22473333/article/details/115045266