栈混洗的概念
A
中的元素经S
的中转后压入B
中,其间,只允许从A
弹出压入S
或者从S
弹出压入B
,A
中元素全部转移到B
中即完成一次栈混洗操作
栈混洗的甄别
对于这个问题主要就是模拟一次栈混洗来解决,即每次
S.pop()
之前检测S
是否已空,或需要弹出的元素在S
中却不是顶元素
代码实现
#include "../head.h"
#include <stack>
bool stackPermutation(stack<int> &A, stack<int> &B) {
stack<int> S, temp;
while (!B.empty()) {
temp.push(B.top());
B.pop();
}
while (!A.empty()) {
S.push(A.top());
A.pop();
if (temp.top() == S.top()) {
temp.pop();
S.pop();
while (!S.empty()) {
if (temp.top() == S.top()) {
temp.pop();
S.pop();
}
else return false;
}
}
}
return S.empty();
}
int main(int argc, char** argv) {
stack<int> a, b;
int ta, tb;
cout << "the base stack [--->: [";
while (cin >> ta)
a.push(ta);
if (cin.eof())
cout << "endoffile";
cin.clear();
cout << endl;
cout << "the test stack [--->: [";
while (cin >> tb)
b.push(tb);
if (stackPermutation(a, b))
cout << "true" << endl;
else cout << "false" << endl;
return 0;
}
stackPermutation()
函数的逻辑是先将待测试栈B
一个个弹出到一个临时栈temp
中,此时temp
的栈顶就是原来B
的栈底,这样就可以比较容易的来模拟一次栈混洗(因为标准库的栈容器没有下标运算符,只能出此下策),接下来以A
非空为判断标准,一次一个的将元素弹出并压入S
中,然后把temp
的栈顶元素与刚压入S
的元素(刚压入嘛,肯定是栈顶)相比较,如果相同,temp
与S
同时弹出这个相同的元素,接下来如果S
是非空,则说明接下来S
的每个元素与temp
的元素相同且一一对应,所以接下来以S
非空为判断标准,比较一次,弹出一次,一旦有不相等,则说明待测试栈不是给定栈的栈混洗,返回false
,还有一种十分特殊的情况,如果B
的栈底元素(也就是temp
的栈顶元素)在A
中根本就没有,即使A
全部弹出,也不会触发循环里面的return false
,所以,最后要用S
是否为空作为判断依据返回
这里还有个小插曲,
main
函数里面第一次cin
结束按<C-d>
后将cin
流的eofbit
置位了,所以后面那个cin
怎么也输入不了,程序总是报段错误
(猜测与cin.eof()
的条件判断吻合),需要将cin
流状态复位才能继续输入