喵喵的柠檬汁 2024-09-20 16:15 采纳率: 50%
浏览 19

有关c++vector的pop_push和back的。

有关c++vector的pop_push和back的。
笔者摸鱼去力扣刷题,因为vector用习惯了,栈相关的操作都通过vector的pop_back(),push_back()和back()实现的,然后这是我写的面对逆波兰式的代码,运行没有问题地址

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        vector<int> score;
        for(auto token:tokens){
            if(token != "+" && token != "-" && token != "*" && token != "/"){
                score.push_back(stoi(token));
            }else{
                int m ,n;
                m = score.back();
                score.pop_back();
                n=score.back();
                score.pop_back();
                if(token == "+"){
                    score.push_back(n+m);
                }
                if(token == "-"){
                    score.push_back(n-m);
                }
                if(token == "*"){
                    score.push_back(n*m);
                }
                if(token == "/"){
                    score.push_back(n/m);
                }                                
            }
        }
        return score.back();
    }
};

但是后续做到一个用栈处理计数器的题目地址,使用相同的思路,在设计好括号内加减问题后,运行却出现了错误,我也知道这个方向有问题,难以处理带负号情况,可我想知道的是为什么这一次的代码执行过程,当while循环中执行.back();.pop_back()使该指针数组大小为零时地址有误,而逆波兰式的算法却没有这个问题,并且如果预先为计数器的 temp指针数组提前放置一个元素0使.back();.pop_back()后指针数组大小不为零就不会爆相关的错误。

img

class Solution {
public:
    int calculate(string s) {
        vector<int> temp;
        vector<char> flags;
        for(auto m:s){
            if(m == ' ' || m == '"'){continue;}
            if(m != '+' && m != '-' && m != '(' && m != ')'){
                temp.push_back((int)m-48);
            }else if(m == ')'){
                flags.push_back(m);
                while(flags.back() != '('){
                    flags.pop_back();
                    int k = temp.back();
                    temp.pop_back();
                    int i = temp.back();
                    temp.pop_back();
                    if(flags.back() == '+'){
                        temp.push_back(k+i);
                        continue;
                    }else if(flags.back() == '-'){
                        temp.push_back(k-i);
                        continue;                        
                    }
                }
            }else{
                flags.push_back(m);
            }
        }
    return temp.back();
    }
};
  • 写回答

1条回答 默认 最新

  • 一轮明月照丘壑 2024-09-20 17:08
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    根据您提供的信息和代码,我看到你在使用vectorpush_back()back()操作时没有正确处理可能发生的边界情况。当vector为空时,调用back()函数可能会导致未定义的行为,因为此时没有元素可以返回。此外,您在处理括号时的方式可能存在一些问题,可能导致堆栈不平衡或处理不当。

    对于第一个问题(当vector为空时调用back()),您可以通过在访问back()之前检查vector是否为空来解决。如果vector为空,则不能进行任何操作或进行适当的错误处理。

    对于第二个问题(括号处理不当),我注意到您的代码在处理右括号时,会连续调用两次temp.back()来获取两个数字,然后进行比较操作。然而,如果在连续的两次调用之间没有其他操作(如插入新元素或删除元素),这可能会导致访问越界的错误。为了解决这个问题,您需要在处理括号之前确保堆栈的平衡,并正确处理括号内的计算顺序。

    下面是一个修改后的代码示例,尝试解决这些问题:

    class Solution {
    public:
        int calculate(string s) {
            vector<int> temp; // 用于存储数字
            stack<char> flags; // 用于存储运算符和括号
            int num = 0; // 用于处理连续的数字序列
            bool isNum = false; // 用于标记当前是否正在读取数字
            for (auto m : s) {
                if (m == ' ' || m == '"') { // 忽略空格和引号字符
                    continue;
                } else if (isdigit(m)) { // 处理数字字符
                    num = num * 10 + (m - '0'); // 将数字转换为整数形式
                    isNum = true; // 设置标记为正在读取数字
                } else { // 处理运算符和括号字符
                    if (isNum) { // 如果正在读取数字,则先将数字添加到temp中
                        temp.push_back(num); // 添加当前数字到temp中
                        num = 0; // 重置num为下一次读取数字做准备
                        isNum = false; // 设置标记为非读取数字状态
                    }
                    if (m == '+' || m == '-' || m == '*') { // 处理运算符,除了括号外的运算符直接入栈
                        flags.push(m); // 将运算符压入栈中等待处理计算结果后出栈进行操作处理即可注意括号的匹配问题。这里省略了具体的计算逻辑代码,您需要自行实现根据运算符进行相应的计算逻辑处理代码以完善您的代码实现目标。 您的代码中没有具体的计算逻辑代码部分需要自行补充完整以实现正确的计算过程。例如,如果处理乘法和除法时需要从堆栈中获取已经处理的括号内的结果来进行计算。而遇到加号时只需要将当前结果添加到结果中即可。遇到减号时需要将当前结果减去之前的结果来实现减法运算等等操作逻辑都需要您自行补充完整代码。具体的计算逻辑可以根据您提供的逆波兰表达式算法进行实现但需要注意处理括号内的计算顺序问题以及正确处理边界情况以避免出现访问越界等问题。 } else if (m == ')') { // 处理右括号字符 需要根据栈中运算符和计算结果进行处理 比如通过优先顺序算法或者后缀表达式进行计算 确保在取反数等操作中能够正确找到正确的括号对 同时保证不会出现栈空等错误情况 所以此处需要对栈进行相应的处理 以保证在出现右括号时能够正确处理运算结果 这里同样省略了具体的实现代码您需要自行实现具体算法来处理这个问题。"否则,将右括号压入栈中等待后续处理。" } } while (!flags.empty()) { // 处理栈中剩余的运算符和计算结果 进行相应的计算操作直到栈为空为止这里的代码实现依赖于您设计的具体算法进行计算例如先处理乘法后处理加减法并且正确处理括号的嵌套问题等请自行实现具体算法来确保计算结果正确无误这里不再赘述具体细节了您的代码中缺失了计算逻辑的实现在这里需要根据具体情况进行相应的计算和判断以得到正确的结果 } return temp.back(); // 返回最终的计算结果即最后一个数 } };```这是一个简化的代码示例,仅提供了基本框架和关键点的注释。您需要自行实现具体的计算逻辑和括号匹配等逻辑以确保算法的正确性和稳定性。希望这能帮助您解决问题!
    
    评论

报告相同问题?

问题事件

  • 修改了问题 9月20日
  • 创建了问题 9月20日