1.逆波兰表达式求数值
描述:给定一个逆波兰表达式,求表达式的值。数据范围:表达式长度满足 1≤n≤104 1≤n≤104 ,表达式中仅包含数字和 + ,- , * , / ,其中数字的大小满足 ∣val∣≤200 ∣val∣≤200 。
这题其实就是一个后缀表达式,将数值压入栈,遇到操作符,就将最上面两个数出栈,计算完之后再压入栈。
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param tokens string字符串vector
* @return int整型
*/
int evalRPN(vector<string>& tokens) {
// write code here
stack<string> 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 <iostream>
#include <stack>
using namespace std;
int main() {
stack<char> s;
string s1;
cin>>s1;
for(int i=0;i<s1.size();i++){
if(s.empty()){
s.push(s1[i]);
}
else{
if(s.top()==s1[i]){
s.pop();
}
else{
s.push(s1[i]);
}
}
}
if(s.empty()){
cout<<0<<endl;
return 0;
}
stack<char>s2;
while(!s.empty()){
s2.push(s.top());
s.pop();
}
while(!s2.empty()){
cout<<s2.top();
s2.pop();
}
cout<<endl;
return 0;
}
// 64 位输出请用 printf("%lld")
3.表达式求值
描述:请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:0≤∣s∣≤1000≤∣s∣≤100,保证计算结果始终在整型范围内
要求:空间复杂度: O(n)O(n),时间复杂度 O(n)O(n)
这题其实可以转化为上面第一题的问题,就是多了一个将中缀表达式转化为后缀表达式的过程。也可以用来两个栈分别存储数据和操作符,直接计算。
#include <stack>
#include <string>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回表达式的值
* @param s string字符串 待计算的表达式
* @return int整型
*/
void oprete(stack<char>& op, stack<int>& 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<char> op;
stack<int> 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();
}
};
谢谢阅读!