表达式求值
一、栈
1. 意义
栈,后进先出 的一种数据结构( L I F O \tt LIFO LIFO),是只能在某一端插入和删除的特殊线性表,进行删除和插入的一端称作栈顶,另一端称作栈底。
2. 数组模拟
(1) 初始化
const int n = 105;
int s[n];
int top = 0;
(2) 相关函数
void push(int x) {
if (top < n) {
s[++top] = x;
} else {
// 上溢处理...
}
}
void pop() {
if (top > 0) {
top--;
} else {
// 下溢处理...
}
}
int getTop() {
return s[top];
}
bool isEmpty() {
return (top == 0);
}
int sizeStack() {
return top;
}
二、例题
1. 车厢调度
小明暑假来到火车站参与暑期实践,这里每辆火车从 A \tt A A 驶入,再从 B \tt B B 方向驶出,同时它的车厢可以重新组合。假设从 A \tt A A 方向驶来的火车有 n n n 节( n ≤ 1000 n\le1000 n≤1000),分别按照顺序编号为 1 ∼ n 1\sim n 1∼n。假定在进入车站前,每节车厢之间都不是连着的,并且它们可以自行移动到 B \tt B B 处的铁轨上。另外假定车站 C \tt C C 可以停放任意多节车厢。但是一旦进入车站 C \tt C C,它就不能再回到 A \tt A A 方向的铁轨上了,并且一旦当它进入 B \tt B B 方向的铁轨,它就不能再回到车站 C \tt C C。负责车厢调度的工作人员需要知道能否使它以 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an 的顺序从 B \tt B B 方向驶出,请判断能否得到指定的车厢顺序。
#include <iostream>
#include <stack>
using namespace std;
int n, x;
int num = 1;
stack <int> s;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x;
while (num <= x) s.push(num++);
if (s.top() != x) {
cout << "NO";
return 0;
} else {
s.pop();
}
}
cout << "YES";
return 0;
}
2. 括号匹配 3.0
#include <iostream>
#include <cstdio>
#include <stack>
#include <string>
using namespace std;
string str;
int n, d[280];
stack<int> s;
int main() {
freopen("bracket.in", "r", stdin);
freopen("bracket.out", "w", stdout);
d['<'] = 4, d['>'] = -4;
d['('] = 3, d[')'] = -3;
d['['] = 2, d[']'] = -2;
d['{'] = 1, d['}'] = -1;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> str;
bool flag = true;
for (char c : str) {
if (d[c] >= 0) {
if (s.empty() || d[c] >= s.top()) s.push(d[c]);
else {
flag = false;
break;
}
} else {
if (s.empty() || s.top() + d[c] != 0) {
flag = false;
break;
} else {
s.pop();
}
}
}
if (flag && s.size() == 0) cout << "YES\n";
else cout << "NO\n";
while (!s.empty()) s.pop();
}
fclose(stdin);
fclose(stdout);
return 0;
}
3. [USACO11FEB] Best Parenthesis S
Recently, the cows have been competing with strings of balanced parentheses and comparing them with each other to see who has the best one.
Such strings are scored as follows (all strings are balanced): the string '()'
has score
1
1
1; if 'A'
has score
s
(
A
)
s(A)
s(A) then '(A)'
has score
2
×
s
(
A
)
2\times s(A)
2×s(A); and if 'A'
and 'B'
have scores
s
(
A
)
s(A)
s(A) and
s
(
B
)
s(B)
s(B), respectively, then 'AB'
has score
s
(
A
)
+
s
(
B
)
s(A)+s(B)
s(A)+s(B). For example, s('(())()')
=
=
= s('(())')+s('()')
=
2
×
= 2\times
=2× s('()')
+
1
=
2
×
1
+
1
=
3
+1 = 2\times 1+1 = 3
+1=2×1+1=3.
Bessie wants to beat all of her fellow cows, so she needs to calculate the score of some strings. Given a string of balanced parentheses of length
N
N
N(
2
≤
N
≤
100
,
000
2 \le N \le 100,000
2≤N≤100,000), help Bessie compute its score.
#include <iostream>
#include <stack>
#define int long long
using namespace std;
const int MOD = 12345678910;
int n, x, top;
int s[1001000];
signed main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x;
if (x == 0) s[++top] = 0;
else {
if (s[top] == 0) {
s[top-1] = (s[top-1] + 1) % MOD;
top--;
} else {
s[top-1] = (s[top-1] + s[top] * 2) % MOD;
top--;
}
}
}
cout << s[0];
return 0;
}
4. 前缀表达式求值
#include <iostream>
#include <string>
using namespace std;
int x, k = 1, num;
int s[100], top;
char c;
string a;
int main() {
cin >> a;
for (int i = a.length()-2; i >= 0; i--) {
c = a[i];
if (c >= '0' && c <= '9') {
num = (c-'0')*k+num;
k *= 10;
} else if (c == '.') {
s[++top] = num;
k = 1, num = 0;
} else {
x = s[top--];
if (c == '+') s[top] = x + s[top];
else if (c == '-') s[top] = x - s[top];
else if (c == '*') s[top] = x * s[top];
else if (c == '/') s[top] = x / s[top];
}
}
cout << s[top];
return 0;
}