像是自助餐廳的餐盤架,最新補充的乾淨餐盤堆疊在上方,客人取用餐盤時,從最上方的開始拿。

# 基本用法

名稱意義
stack<int> sk建立一個 int 型別的 stack
sk.size()堆疊元素數量
sk.empty()判斷堆疊是否為空
sk.push(x)從堆疊「頂端」加入一個元素 x
sk.pop()刪除堆疊頂端元素
sk.top()取得堆疊頂端元素

刪除 sk.top() 並不會刪除頂端元素

# 上課例題

# a034: 二進位制轉換

將一個 10 進位的數字換成二進位數字

每一次就對 n 做一次取餘數,並記錄下來,
再往右邊推移位 (除以二) 直到 n 等於 0 為止。
之後,再倒著輸出出來就好了啊!!

#include<iostream>
using namespace std;
int main(){
    int n,i;
    int a[1000];
    while(cin>>n){
        i=-1;
        while(n){
            a[++i]=n%2;
            n/=2;
        }
        for(int j =i; j>=0;j--)
            cout<<a[j];
        cout<<endl;
    }
}

因為結果是倒著輸出的部分可以使用 stackLast In First Out 特性將陣列替代掉。

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        stack<int>s;
        while(n){
            s.push(n%2);
            n/=2;
        }
        while(s.size()){
            cout<<s.top();
            s.pop();
        }
        cout<<endl;
    }
}

# b838: 104 北二 2. 括號問題

請你寫一個程式判斷一個式子中的括號是否正確,
若正確的話,請輸出式子中有幾對括號,
若錯誤的話,請輸出 0。

讀入一個 ( 就加入堆疊,讀入一個 ) 就刪除一個堆疊中的 (
若運算中,堆疊元素量不足為不合法;
運算結束後,若堆疊能有元素亦為不合法。

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        cin.ignore();
        while(n--){
            stack <char> st;
            string s;
            bool flag = true;
            int ans=0;
            getline(cin,s);
            for(int i=0;i<s.size();i++){
                if(s[i]=='(') st.push('(');
                else if(s[i]==')') {
                    if(!st.empty())st.pop(), ans++;
                    else  { cout<<"0\n" ; flag=false; break; }
                }
            }
            if(!st.empty()) { cout<<"0\n"; flag=false; }
            if(flag) cout<<ans<<endl;
        }
    }
}

# 延伸練習

# b923: stack 堆疊的模板題

實作 stack 的幾種操作

  1. 刪除堆頂元素
  2. 輸出頂端元素
  3. 丟數字進堆疊
#include <iostream>
#include<stack>
using namespace std;
int main(){
    stack<int> sk;
    int n;
    cin>>n;
    while(n--){
        int m;
        cin>>m;
        if(m==3){
            int temp;
            cin>>temp;
            sk.push(temp);
        }
        else if(m==2)
            cout<<sk.top()<<endl;
        else
            sk.pop();
    }
}

# d318: 11185 - Ternary

將一個 10 進位的數字換成三進位數字

跟轉換二進位的過程及方式一樣,只需要改成取 3 的餘數即可

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        stack<int>s;
        if(n==0){
            cout<<0<<endl;
            continue;
        }
        if(n<0){
            break;
        }
        while(n){
            s.push(n%3);
            n/=3;
        }
        while(s.size()){
            cout<<s.top();
            s.pop();
        }
        cout<<endl;
    }
}

# a132: 10931 - Parity

整數 n 的「同位元」定義為:其二進位表示法中每位元的和再除以 2 的餘數。
計算一個整數 1 ≤ I ≤ 2147483647 的同位元。

運用 stack 將數字先轉為二進位,
並再將所有的一的數量記錄下來即可。

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n&&n){
        stack<int>s;
        int cnt = 0;
        while(n){
            s.push(n%2);
            if(n%2) cnt++;
            n/=2;
        }
        cout<<"The parity of ";
        while(s.size()){
            cout<<s.top();
            s.pop();
        }
        cout<< " is "<<cnt<<" (mod 2).\n";
    }
}

# a565: 2.p&q 的邂逅

每一組名單中,p 與 q 之間可能相鄰或者以「.」分隔,「.」的數量多寡不定,
目標就是盡量找出所有可以配成對的 p 與 q。

建立一個空的堆疊,
每當讀到一個 p 就將其加入堆疊,
若讀到 q 則判斷堆疊是否為空,
若不為空,則將從堆疊上取走一個 p,並總數加一,否則忽視。

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    scanf("%d\n",&n);
    while(n--){
        stack <char> sk;
        int cnt=0;
        while(true){
            char c = getchar();
            if(c=='.')
                continue;
            else if(c=='p')
                sk.push('p');
            else if(c=='q')
                if(!sk.empty()&&sk.top()=='p')
                    sk.pop(),cnt++;
            else
                break;
        }
        printf("%d\n",cnt);
    }
}
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay