9月7日算法学习笔记(栈)

1.逆波兰表达式求数值

描述:给定一个逆波兰表达式,求表达式的值。数据范围:表达式长度满足 1≤n≤104 1≤n≤104 ,表达式中仅包含数字和 + ,- , * , / ,其中数字的大小满足 ∣val∣≤200 ∣val∣≤200 。

这题其实就是一个后缀表达式,将数值压入栈,遇到操作符,就将最上面两个数出栈,计算完之后再压入栈。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param tokens string字符串vector 
     * @return int整型
     */
    int evalRPN(vector& tokens) {
        // write code here
        stack stk;
        int n1, n2, res;
        for (string &s : tokens) {
            if (s == "+" || s == "-" || s == "*" || s == "/") {
                n2 = stoi(stk.top());
                stk.pop();
                n1 = stoi(stk.top());
                stk.pop();
                if (s == "+") res = n1 + n2;
                else if (s == "-") res = n1 - n2;
                else if (s == "*") res = n1 * n2;
                else res = n1 / n2;
                stk.push(to_string(res));
            } else stk.push(s);
        }
        return stoi(stk.top());
    }
};

2.点击消除

描述:牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?

输入描述:
一个字符串,仅由小写字母组成。(字符串长度不大于300000)

输出描述:
一个字符串,为“点击消除”后的最终形态。若最终的字符串为空串,则输出0。

这题其实用队列更好,但是既然是练习栈的算法,那么也继续用栈,将字符串压入栈,然后当栈顶值与该值相同时,就将栈顶出栈,达到消除的效果。但是要注意的是,将最后结果出栈的时候,是先进后出的,要达到题目的效果就得再搞一个栈,压入了再出栈。

#include 
#include 
using namespace std;

int main() {
    stack s;
    string s1;
    cin>>s1;
    for(int i=0;is2;
    while(!s.empty()){
        s2.push(s.top());
        s.pop();
    }
    while(!s2.empty()){
        cout<

3.表达式求值

描述:请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:0≤∣s∣≤1000≤∣s∣≤100,保证计算结果始终在整型范围内
要求:空间复杂度: O(n)O(n),时间复杂度 O(n)O(n)

这题其实可以转化为上面第一题的问题,就是多了一个将中缀表达式转化为后缀表达式的过程。也可以用来两个栈分别存储数据和操作符,直接计算。

#include 
#include 
class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    void oprete(stack& op, stack& digital) {
        int right = digital.top();
        digital.pop();
        int left = digital.top();
        digital.pop();
        if (op.top() == '*') digital.push(left * right);
        if (op.top() == '+') digital.push(left + right);
        if (op.top() == '-') digital.push(left - right);
        op.pop();
    }
    int solve(string s) {
        int n = s.length();
        stack op;
        stack digital;
        for (int i = 0; i < n;) {
            if (s[i] - '0' >= 0 && s[i] - '0' <= 9) {
                int j;
                int num = 0;
                for (j = i; j < n; j++) {
                    if (s[j] - '0' >= 0 && s[j] - '0' <= 9) {
                        num = num * 10 + s[j] - '0';
                    } else break;
                }
                digital.push(num);
                i = j;
                continue;
            } else if (op.empty()) {
                op.push(s[i++]);
                continue;
            }
            if (s[i] == '(') {
                op.push(s[i++]);
                continue;
            } else if (s[i] == '-' || s[i] == '+') {
                while (!op.empty() && op.top() != '(')oprete(op, digital);
                op.push(s[i]);
            } else if (s[i] == '*') {
                while (op.top() == '*')oprete(op, digital);
                op.push(s[i]);
            } else {
                while (op.top() != '(')oprete(op, digital);
                op.pop();
            }
            i++;
        }
        oprete(op, digital);
        return digital.top();
    }
};

谢谢阅读!

你可能感兴趣的:(算法,学习,笔记,数据结构)