【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++)

这篇具有很好参考价值的文章主要介绍了【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 前言(栈适用于解哪些题?)

栈适合解决需要后进先出(LIFO)的结构的算法题,例如:

  1. 括号匹配问题:判断给定字符串中括号是否匹配。
  2. 表达式求值问题:将表达式转换为后缀表达式,并计算其值。
  3. 逆波兰表达式问题:将表达式转换为逆波兰表达式,并计算其值。
  4. 直方图最大矩形面积问题:给定一个直方图,求最大的矩形面积。
  5. 进制转换问题:将一个十进制数转换为任意进制的数。
  6. 迷宫问题:在迷宫中寻找从起点到终点的路径。

我们下面会选择一部分题并用栈来进行解题:

2. 算法题

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

【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

思路

  • 题意分析:要求将字符串中所有连续的字符删去,如下图所示:
    【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

  • 解法用栈模拟这个过程

    • 创建一个string类来作为栈
    1. 将s中的元素依次入栈,每次判断站栈顶元素是否等于当前元素
    2. 如果是,则删去栈顶元素,如果不是则将该元素入栈

代码文章来源地址https://www.toymoban.com/news/detail-795443.html

string removeDuplicates(string s) {
   // 解法:用栈模拟过程
    string st;
    for(char ch : s)
    {
        if(!st.empty() && st.back() == ch)
            st.pop_back();
        else
            st += ch;
    }

    return st;
}

844.比较含退格的字符串

【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

思路

  • 题意分析:即比较两个字符串在退格后是否相同,
  • 解法用栈模拟这个过程
    1. 分别对两个字符串创建栈来模拟(用字符串表示栈)
    2. 如果 遇到#且栈不为空,则删除栈顶元素,否则将当前元素入栈。

代码

bool backspaceCompare(string s, string t) {
    // 栈模拟退格删除元素过程
    string st1 = "";
    for(char ch : s)
    {
        if(ch != '#')
            st1.push_back(ch);
        else if(ch == '#' && !st1.empty())
            st1.pop_back();
    }

    string st2 = "";
    for(char ch : t)
    {
        if( ch != '#')
            st2.push_back(ch);
        else if(ch == '#' && !st2.empty())
            st2.pop_back();
    }

    return st1 == st2;
}

227.基本计算器II

【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

思路

  • 题意分析:该题属于一个表达式求值题,即计算一个表示表达式的字符串的值。该题中s仅由’+‘、’-‘、’*‘、’/’ 四个符号组成。

  • 解法利用栈进行计算(数组表示栈)
    【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

    • 上面的是使用栈解决这道题的总体算法思想,下面是步骤细节注意.
    1. 定义sym用于记录符号字符,数组表示栈
    2. 从头遍历字符串,根据当前字符进入不同分支
      • 如果是空格,直接跳过该位,i++
      • 如果是符号,则sym记录当前符号后,i++
      • 如果是数字
        • 由于表达式中的数不一定是个位数,所以先利用循环找到当前位置的数
    3. 之后根据sym存储的符号对tmp和栈顶元素进行处理(即图中步骤)
    4. 最后累加元素

代码

int calculate(string s) {
    // 用一个栈存储数字字符,定义sym记录遇到的符号
    // sym='+' : 直接将下一位tmp加到栈中
    // sym='-' : 将-tmp加入到栈中
    // sym='*' : 栈顶元素 *= tmp
    // sym='/' : 栈顶元素 /= tmp
    char sym = '+';
    vector<int> st; // 数组作栈
    int i = 0, n = s.size();
    while(i < n)
    {
        if(s[i] == ' ') i++;
        else if(s[i] >= '0' && s[i] <= '9')
        {
            int tmp = 0;
            while(s[i] >= '0' && s[i] <= '9')
            	// 循环:tmp记录当前数字 并将其由字符串转为整形)
                tmp = tmp * 10 + (s[i++] - '0');

            if(sym == '+') st.push_back(tmp);
            else if(sym == '-') st.push_back(-tmp);
            else if(sym == '*') st.back() *= tmp;
            else st.back() /= tmp;
        }
        else
        {
            sym = s[i++];
        }
    }

    int ret = 0;
    // 将栈中所有元素累加
    for(auto x : st)
        ret += x;

    return ret;
}

394.字符串解码

【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

思路

  • 题意分析:看示例便很好理解,通过将 “数字[字符]” 解码为 “数字次字符串

  • 解法利用栈进行计算/font>
    【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

    • 上图为用栈解决该题的总体算法思路,下面是简单的部分注意事项
    • 遇到 ‘[’ 时,我们向 “字符串栈” 加入空串,便于后面的字符串加入到"字符串栈"中
    • 最后结果就是字符串的栈顶元素

代码

string decodeString(string s) {
    // 栈模拟过程 : 字符串栈sst 整形栈 ist
    vector<string> sst;
    sst.push_back(""); // 初始化栈顶元素为空串
    vector<int> ist;
    // 遍历字符串,四种情况:
    // 1. 遇到数字:放入ist
    // 2. 遇到字符串 : 放到sst栈顶元素的后一位
    // 3. 遇到左括号 : 将空字符串 "" 加入到 sst 的栈顶
    // 4. 遇到右括号 : 合并两栈栈顶元素(即重复字符串)
    int i = 0, n = s.size();
    string tmp = "";
    while(i < n)
    {
        if(s[i] >= '0' && s[i] <= '9')
        {
            int num = 0;
            // 数字并不一定是个位、
            while(isdigit(s[i]))
                num = num * 10 + (s[i++] - '0');
            ist.push_back(num);
            continue;
        }
        else if(s[i] >= 'a' && s[i] <= 'z')
        {
            tmp = "";
            while(s[i] >= 'a' && s[i] <= 'z' && i < n)
                tmp += s[i++]; // 记录该字符串
            sst[sst.size() - 1] += tmp; // 加到栈顶后一位
            continue;
        }
        else if(s[i] == '[')
        {
            sst.push_back(""); // 新建空串
        }
        else // s[i] == ']'
        {
            // 合并两栈顶元素(重复字符串)
            tmp = sst.back();
            int x = ist.back();
            ist.pop_back();
            sst.pop_back();
            while(x--)
                sst.back() += tmp;
        }
        ++i;
    }

    return sst.back();
}

946.验证栈序列

【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++),算法,算法,c++,开发语言

思路

  • 题意分析:标准的用栈模拟过程的题,即根据题目给出的pushed和poped数组来判断该输入、弹出顺序是否合法。
  • 解法利用栈模拟过程
    1. 定义两指针分别表示当前待入栈元素的位置和当前要弹出的元素在出栈序列中的位置
    2. 进入循环,判断当前的状态是否合法
      • 合法则将该元素弹出栈
      • 不合法则将当前待入栈元素压入辅助栈中,并将cur1指针后移
    3. 当所有的元素都入栈之后,如果辅助栈中还有元素,说明出栈序列不合法

代码

bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
    stack<int> st; // 辅助栈
    int cur1 = 0, cur2 = 0;
    while (cur2 < popped.size()) 
    {   // 出栈序列结束,则合法
        if (!st.empty() && st.top() == popped[cur2]) 
        {
            st.pop();
            cur2++;
        }
        else if (cur1 < pushed.size())
            st.push(pushed[cur1++]);
        else
            return false;
    }
    return true;
}

到了这里,关于【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • hive中使用正则表达式匹配数字

    2024年02月14日
    浏览(37)
  • java14 使用增强的模式匹配切换表达式

    野旷天低树,江清月近人。——唐代杜甫《月夜忆舍弟》 使用增强的模式匹配切换表达式(Switch Expressions with Enhanced Pattern Matching) Java 14中引入的“Switch Expressions with Enhanced Pattern Matching”这个功能。 这个功能可以让我们在使用switch case语句时,同时进行类型检查和类型转换,从

    2023年04月08日
    浏览(24)
  • 【正则表达式】正则表达式常见匹配模式

    模式 描述 w 匹配字母数字及下划线 W 匹配非字母数字下划线 s 匹配任意空白字符,等价于 [tnrf]. S 匹配任意非空字符 d 匹配任意数字,等价于 [0-9] D 匹配任意非数字 A 匹配字符串开始 Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 z 匹配字符串结

    2024年02月09日
    浏览(65)
  • 正则表达式 (用于灵活匹配文本的表达式)

    目录 . * 用于匹配任意单个字符,除了换行符。 例如使用正则表达式 a.b, 它可以匹配aab、acb、a#b 用于匹配前一个字符零次或多次。 例如,使用正则表达式 ab*c ,它可以匹配 \\\"ac\\\"、\\\"abc\\\"、\\\"abbc\\\",因为 b* 表示匹配零个或多个字符 \\\"b\\\"。所以,这个表达式可以匹配 \\\"ac\\\"(零个 \\\"b\\\"),

    2024年01月16日
    浏览(52)
  • learn_C_deep_11 (深刻理解整形提升、左移和右移规则、花括号、++和--操作、表达式匹配:贪心算法)

    深刻理解整形提升 左移和右移规则 如何理解\\\"丢弃\\\" 一个问题  0x012+3 的值是多少 花括号 ++、--操作 表达式匹配:贪心算法 char类型的c经过按位取反、左移和右移是不是char类型了?为什么char类型的c加了操作符运算求空间大小就不是1了呢?         无论任何位运算符,目

    2024年02月05日
    浏览(28)
  • java中通过split方法使用分号分割,使用正则表达式匹配不识别单引号中的分号

    在Java中,使用split()方法可以通过指定正则表达式作为分隔符来拆分字符串。如果你想忽略单引号内的分号,可以使用以下代码: 在这个正则表达式中,它使用反向零宽断言 (?!...) 和顺序零宽断言 (?=...) 来限制分隔符的匹配位置,以确保只有在非单引号内部的位置才会进行分

    2024年02月08日
    浏览(38)
  • 正则表达式的神奇世界:表达、匹配和提取

    正则表达式,这个看起来像密林中的迷宫的工具,既神秘又令人着迷。它是编程世界中的一门魔法,有着神奇的能力。你是否曾经在寻找或解析文本时感到束手无策?或许你想要从海量数据中提取特定信息?这正是正则表达式可以派上用场的时候。本文将带你探索这个神奇的

    2024年02月07日
    浏览(49)
  • Java 正则表达式匹配

    正则表达式: 定义一个搜索模式的字符串。 正则表达式可以用于搜索、编辑和操作文本。 正则对文本的分析或修改过程为:首先正则表达式应用的是文本字符串(text/string),它会以定义的模式从左到右匹配文本,每个源字符只匹配一次。 正则表达式 匹配 this is text 精确匹配

    2024年02月06日
    浏览(46)
  • 【动态规划】通配符匹配与正则表达式匹配

    题目描述: 给你一个输入字符串 (s) 和一个字符模式 § ,请你实现一个支持 ‘?’ 和 ‘*’ 匹配规则的通配符匹配: ‘?’ 可以匹配任何单个字符。 ‘*’ 可以匹配任意字符序列(包括空字符序列)。 判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而

    2024年02月07日
    浏览(45)
  • VSCode 正则表达式 匹配多行

    VS Code 正则表达式匹配多行 (.|n)*? 案例1: str(.|n)*?, 案例2: const(.|n)*?}$ 案例3: fn(.|n)*?},

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包