当前位置: 首页 > article >正文

专题十一——栈

目录

1删除字符串中的所有相邻重复项

2比较含退格的字符串

3基本计算器Ⅱ 

4字符串解码

5验证栈序列

6基本计算器 


1删除字符串中的所有相邻重复项

oj链接:删除字符串中的所有相邻重复项

// stack
class Solution
{
public:
    string removeDuplicates(string s)
    {
        stack<int> st;
        for (auto &ch : s)
        {
            if (!st.empty() && ch == st.top())
                st.pop();
            else
                st.push(ch);
        }
        string ret;
        while (!st.empty())
        {
            ret += st.top();
            st.pop();
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};
// string
class Solution
{
public:
    string removeDuplicates(string s)
    {
        string ret;
        for (auto &ch : s)
        {
            if (ret.size() != 0 && ret.back() == ch)
                ret.pop_back();
            else
                ret.push_back(ch);
        }
        return ret;
    }
};

2比较含退格的字符串

oj链接:比较含退格的字符串

class Solution
{
public:
    bool backspaceCompare(string s, string t)
    {
        return ChangeStr(s) == ChangeStr(t);
    }
    string ChangeStr(string &s)
    {
        string ret;
        for (auto &ch : s)
        {
            if (ch != '#')
                ret += ch;
            else if (ret.size())
                ret.pop_back();
        }
        return ret;
    }
};

//解法2:双栈->下题的思路
class Solution
{
public:
    unordered_map<char, int> prior = {
        {'+', 0},
        {'-', 0},
        {'*', 1},
        {'/', 1}};
    int calculate(string s)
    {
        stack<int> val;
        stack<char> ops;
        val.push(0);
        int n = s.size(), i = 0;
        while (i < n)
        {
            if (s[i] == ' ')
                i++;
            else if (s[i] >= '0' && s[i] <= '9')
            {
                int tmp = 0;
                while (i < n && s[i] >= '0' && s[i] <= '9')
                    tmp = tmp * 10 + (s[i++] - '0');
                val.push(tmp);
            }
            else
            {
                char op = s[i];
                while (!ops.empty() && prior[op] <= prior[ops.top()])
                    cal(val, ops);
                ops.push(op);
                i++;
            }
        }
        while (!ops.empty())
            cal(val, ops);
        return val.top();
    }
    void cal(stack<int> &val, stack<char> &ops)
    {
        int a = val.top();
        val.pop();
        int b = val.top();
        val.pop();
        char op = ops.top();
        ops.pop();
        if (op == '+')
            val.push(b + a);
        else if (op == '-')
            val.push(b - a);
        else if (op == '*')
            val.push(b * a);
        else
            val.push(b / a);
    }
};

3基本计算器Ⅱ 

oj链接:基本计算器 II

但此种解法不通用,如果有括号的加入就失效了! 

class Solution {
public:
    int calculate(string s) {
        stack<int> st;
        char oper='+';//初始化
        int n=s.size(),i=0;

        while(i<n)
        {
            if(s[i]==' ') i++;
            else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/')
            {
                oper=s[i];
                i++;
            }
            else
            {
                int tmp=0;
                while(i<s.size()&&s[i]>='0'&&s[i]<='9')
                {
                    tmp=tmp*10+(s[i]-'0');
                    i++;
                }
                if(oper=='+') st.push(tmp);
                else if(oper=='-') st.push(-tmp);
                else if(oper=='*'&&!st.empty()) st.top()*=tmp;
                else st.top()/=tmp;
                //此时i在下个位置
            }
        }
        long long ret=0;
        while(!st.empty())
        {
            ret+=st.top();
            st.pop();
        }
        return ret;
    }
};

4字符串解码

oj链接:字符串解码

class Solution
{
public:
    string decodeString(string s)
    {
        stack<int> val;
        stack<string> op;
        op.push(""); // 细节
        int n = s.size(), i = 0;
        while (i < n)
        {
            if (s[i] >= '0' && s[i] <= '9')
            {
                int tmp = 0;
                while (i < n && s[i] >= '0' && s[i] <= '9')
                    tmp = tmp * 10 + (s[i++] - '0');
                val.push(tmp);
            }
            else if (s[i] == '[')
            {
                i++; // 细节:i++不然后死循环
                string tmp;
                while (i < n && s[i] >= 'a' && s[i] <= 'z')
                    tmp += s[i++];
                op.push(tmp);
            }
            else if (s[i] == ']')
            {
                Decode(val, op);
                i++;
            }
            else
            {
                // 遇到单独字符(串)
                string tmp;
                while (i < n && s[i] >= 'a' && s[i] <= 'z')
                    tmp += s[i++];
                op.top() += tmp;
            }
        }
        return op.top();
    }
    void Decode(stack<int> &val, stack<string> &op)
    {
        int a = val.top();
        val.pop();
        string s = op.top();
        op.pop();
        string tmp;
        for (int i = 0; i < a; i++)
            tmp += s;
        op.top() += tmp;
    }
};

5验证栈序列

oj链接:验证栈序列

class Solution
{
public:
    bool validateStackSequences(vector<int> &pushed, vector<int> &popped)
    {
        stack<int> st;
        int i = 0, n = popped.size();
        for (auto &push_val : pushed)
        {
            st.push(push_val);
            while (!st.empty() && st.top() == popped[i])
            {
                st.pop();
                i++;
            }
        }
        // if(st.empty()) return true;
        // return false;
        return i == n;
    }
};

 

6基本计算器 

oj链接:基本计算器

解法:双栈(通用解法)
使用两个栈 val 和 op 。

val : 存放所有的数字
op :存放所有的数字以外的字符
2.从前往后遍历,对遍历到的字符进行分类讨论:

a 空格 : 跳过
b ( : 直接加入 op 中
c ) : 使用现有的 val 和 op 进行计算(直到遇到左边最近的一个左括号为止)
d +/- : 需要将操作放入 op 中。在放入之前先把栈内可以算的都算掉,使用现有的 val 和 op 进行计算(直到栈内没有操作符或者遇到左括号后停止)

e 数字 : 从当前位置开始继续往后取,将整一个连续数字整体取出,加入 val 中
细节

1) 由于第一个数可能是负数,为了减少边界判断:遍历之前先往 nums 添加一个 0
2) 为防止 () 内出现的首个字符为运算符,(遍历之前)将所有的空格去掉并将 (- 替换为 (0-,(+ 替换为 (0+(这个处理逻辑可以放到遍历字符串里去做)

class Solution
{
public:
    void ClearSpace(string &s)
    {
        int pos = s.find(" ");
        while (pos != string::npos)
        {
            // s.replace(pos, 1, "");
            s.erase(pos, 1);
            pos = s.find(" ");
        }
    }
    int calculate(string s)
    {
        stack<int> val;
        stack<char> op;
        // 细节1:防止第一个字符为'-',先往val里加0
        val.push(0);
        // 细节2:在遍历前清除空格
        // 为什么不能再遍历中:判断是空格后i++呢?-> 要保证 (+ 或 (- 能判断得出来 -> s[i-1]==')'?
        ClearSpace(s);
        int n = s.size(), i = 0;
        while (i < n)
        {
            if (s[i] == '(')
                op.push(s[i++]);
            else if (s[i] == ')')
            {
                while (op.top() != '(')
                {
                    cal(val, op);
                }
                op.pop();
                i++;
            }
            else if (s[i] == '+' || s[i] == '-')
            {
                // 防止出现 ‘(-’ 或 ‘(+’ 时计算出错 -> 参考用例:"1-(     -2)"
                if (!op.empty() && (s[i - 1] == '('))
                    val.push(0);
                while (!op.empty() && op.top() != '(')
                    cal(val, op);
                op.push(s[i++]);
            }
            else
            {
                int tmp = 0;
                while (i < n && s[i] >= '0' && s[i] <= '9')
                    tmp = tmp * 10 + (s[i++] - '0');
                val.push(tmp);
            }
        }
        while (!op.empty())
            cal(val, op);
        return val.top();
    }
    // 两个数相+/-的逻辑
    void cal(stack<int> &val, stack<char> &op)
    {
        int a = val.top();
        val.pop();
        int b = val.top();
        val.pop();
        char tmp = op.top();
        op.pop();
        if (tmp == '+')
            val.push(a + b);
        else
            val.push(b - a);
    }
};

 以上便是全部内容:有问题欢迎在评论区指正,感谢观看!


http://www.kler.cn/a/405899.html

相关文章:

  • 【ChatGPT】如何设计问题让ChatGPT生成创意写作内容
  • 在Excel中处理不规范的日期格式数据并判断格式是否正确
  • 影响电阻可靠性的因素
  • 2024信创数据库TOP30之蚂蚁集团OceanBase
  • OpenCV 计算图像清晰度
  • 【CSP CCF记录】201903-1第16次认证 小中大
  • 17种Kubernetes安全检测工具详解
  • 解决绿盟漏洞扫描 gateway、nacos、springboot tomcat检测到目标主机可能存在缓慢的HTTP拒绝服务攻击问题
  • Node基本使用
  • Linux KASLR 地址偏移
  • C语言:数组转换指针的时机
  • Sparrow系列拓展篇:对信号量应用问题的深入讨论
  • Spring Cloud OpenFeign 声明式服务调用与负载均衡组件
  • React——useReducer
  • 3D模型平台行业全面深入分析
  • 【DQ Robotics】二次规划控制
  • 金融量化交易模型的探索与发展
  • 鸿蒙系统ubuntu开发环境搭建
  • Windows VScode+Latex环境
  • 华为IPD流程管理体系L1至L5最佳实践-解读
  • 《Shader 入门精要》学习笔记 茵蒂克丝
  • //动态内存分配
  • 深度学习笔记之BERT(二)BERT精简变体:ALBERT
  • 红帽(RHCE)工程师认证
  • 【STM32】BKP备份寄存器RTC实时时钟PWR电源控制
  • 革新车间照明,分布式IO模块引领智能制造新纪元