1. 程式人生 > 實用技巧 >C++之棧的應用-------判斷出棧序列是否合法

C++之棧的應用-------判斷出棧序列是否合法

//合法的出棧佇列
//已知從1至n的數字序列,按順序入棧,每個數字入棧後即可出棧,也可在棧中停留,
//等待後面的數字入棧出棧後,該數字在出棧,求該數字序列的出棧序列是否合法
#include<iostream>
#include<stack>
#include<queue>
using namespace std;

/*
數字序列的合法出棧序列特點,設出棧序列為int a[] = {1,2,3,....i},其中a[i-1]是最後出棧的元素;如a[]是合法的出棧序列,則應該滿足如下條件
1.a[i]>a[i-1]
2.當a[i]<a[i-1]時,
    1)若a[i]+1=a[i-1],a[0]至a[i]之間的出棧序列合法
    2)若a[i]+1<a[i-1],則a[i]+1至a[i-1]-1的數字需要在a[i-1]之前彈出
*/ //利用陣列實現 //很複雜,最差的情況下演算法複雜度為O(n^2) bool isStackSequeue(const int *a,int n) { bool validate = true; //從出棧序列的第二個數開始,到出棧序列的倒數第三個數結束 for (int i = 1; i < n; i++) { if (i == n - 1) { //出棧序列合法,終止迴圈 break; } //如果當前出棧元素a[i]在原始佇列[1:n]中排在前一個元素的後面 if
(a[i] > a[i - 1]) { continue; } if (a[i] < a[i - 1]) { //如果當前的出棧元素比前一個出棧元素小一,則a[0]:a[i]的出棧順序合法 if (a[i] + 1 == a[i - 1]) { continue; } //如果當前出棧元素a[i]與前一個出棧元素a[i-1]在原始佇列相隔多個元素 //判斷兩者之間間隔的元素是否在前一個出棧元素之前出棧了
if (i - 2 + 1 < a[i - 1] - a[i] - 1) { //a[i]:a[i-1]之間的元素並沒有完全出棧,說明出棧佇列不對 validate = false; break; } //遍歷a[i]:a[i-1]之間的元素a[i]+1:a[i-1]-1,觀察它們是否在a[i-1]之前出棧了 for (int m = a[i] + 1; m < a[i - 1]; m++) { //判斷在a[i]+1至a[i-1]-1的元素m是否在a[i-1]之前出棧了 for (int j = 0; j < i - 1; j++) { //如果元素m沒有在a[i-1]之前出棧,則出棧佇列不合法 if (j == i - 2) { if (a[j] == m) { break; } return false; } //元素m在a[i-1]之前出棧了,繼續判斷m+1是否也出棧了 if (a[j] == m) break; } } } } return validate; } //利用棧實現 //演算法複雜度為O(2n) ,只有n個元素進棧出棧(只統計元素進棧和出棧的次數) bool isStackSequeue2(const int* a, int n) { stack<int> s; for (int i = 0; i < n; i++) { if (i == 0) { //當a[i]==1時,模擬數字1的入棧出棧 if (a[i] == 1) { s.push(1); s.pop(); } //當a[i]>1時,模擬1:a[i]之前數字的入棧 else { for (int j = 1; j <= a[i]; j++) s.push(j); //a[i]元素出棧 s.pop(); } } else { //如果當前元素a[i]比前一個元素a[i-1]大,則將a[i-1]:a[i]之間的元素壓入棧 if (a[i] > a[i - 1]) { for (int m = a[i - 1] + 1; m <= a[i]; m++) s.push(m); //a[i]元素出棧 s.pop(); } //如果當前元素a[i]比a[i-1]小,則彈出s的棧頂元素,比較s.top()與a[i]的大小 else { //當前a[i]元素出棧順序合法 if (s.top() == a[i]) { s.pop(); //進入下一個迴圈,驗證a[i+1]元素 continue; } //出棧佇列不合法 return false; } } } return true; } //利用棧和佇列實現 模擬出棧佇列 //演算法複雜度為O(3n),只統計進棧和出棧的次數 bool isStackSequeue3(queue<int> order) { stack<int> s; int n = order.size(); for (int i = 1; i <= n; i++) { s.push(i); while (!s.empty()&&s.top() == order.front()) { s.pop(); order.pop(); } } if (!order.empty()) { return false; } return true; } int main() { int n; cout << "請輸入數字序列的個數n:"; cin >> n; int train = 1; int* a; while (n) { a = new int[n]; queue<int> q; while (train) { cout << "請輸入出棧序列:"; for (int i = 0; i < n; i++) { cin>>train; a[i] = train; q.push(train); } cout << "isStackSequeue:" << isStackSequeue(a, n) << endl; cout << "isStackSequeue2:" << isStackSequeue2(a, n) << endl; cout << "isStackSequeue3:" << isStackSequeue3(q) << endl; cout << "是否繼續(0:退出,1:繼續):"; cin>>train; } delete[] a; cout << "請輸入序列的個數n(輸入0退出):"; cin>>n; } return 0; }