先验:STL库中栈相关的知识。
问题:计算机中后缀表达式的计算,如何实现?
计算机中后缀表达式的写法:
例如:((10 * (6 / ((9 + 3) * -11))) + 17) + 5
在计算机中存储为:nums=["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
假定输入为vector<string> s.输出为计算的结果。
对比nums的格式与表达式的计算顺序,发现每一个运算符总是与其相邻的前两个数字组合,计算得到新值,从而完成一个内层括号运算,新值占据nums中对应的旧值。这个过程用栈来模拟,类似括号的匹配。
using namespace std;
int RPN(vector<string> &nums){
stack<int> s;
//s.push(nums[0]);
unordered_set<string> set={"+", "-", "*", "/"};
for(int i=0;i<nums.size();++i){
if(set.find(nums[i]) !=set.end()){
int num1=s.top();s.pop();
int num2=s.top();s.pop();
if (nums[i] == "+") { s.push(num1 + num2); }
else if (nums[i] == "-") { s.push(num1 - num2); }
else if (nums[i] == "*") { s.push(num1 * num2); }
else { s.push(num2 / num1); }
}
else{
s.push(stoi(nums[i]));
}
}
return s.top();
}
最后思考另一个问题:计算机时如何将一个表达式转换为上述的nums格式的?
上述的nums可以写成二叉树形式,对二叉树进行后续遍历,即得到后缀表达式。
栈应用的经典问题:括号匹配。
给定一组只含有'(',')','[',']','{','}'的括号字符串,判断是否为有效的括号对。例如:“{}()”有效,而“[[}]]”无效。
入栈原则:左括号则入栈。
//
bool BracketMatch(string &str){
stack<char> s;
unordered_set<char> set={'(', '[', '{'};
unordered_map<char, char> map={ {')', '('}, {']', '['}, {'}', '{'}};
for(int i=0;i<str.length();++i){
if(set.find(str[i])==set.end()){s.push(str[i]);}//是左括号,入栈
else{
//str[i]为右括号
if(s.empty()) return false;//如果右括号多,则无法匹配
//查找对应的左括号,使用了map。
if(map[str[i]]!=s.top())return false;
s.pop();
}
}
//str遍历完,此时s应当为空
if(!s.empty()) return false;
return true;
}
栈还有其他很多用法,例如:当user在查找文件时,计算机如何知道user目前正处于哪个路径下?路径回退、前进过程就是通过栈的压入,弹出来管理的。