棧混洗的概念
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
流狀態復位才能繼續輸入