Stack (堆疊)


假設你有一些書把他們疊起來,一層一層的往上疊,所以每次新的書本會放在最上面,而當想要拿取書本的時候,也是從最上面的開始拿。當然現實生活會有可能從中間抽出書本,不過在程式中是不可以的,在程式世界下圖會更貼切。

所以這是一種資料結構,後進先出(Last-In-First-Out, LIFO)

河內塔故事中的每一個柱子都是Stack結構

柱子最上方的盤子,一定是最先被拿起來的

平常生活有時候也會發生 Stack 的情境,人會最優先處理最後發生的事

做事做到一半時,突然一件更緊急的事發生

這時就會先把打斷的事做完,才回來繼續做原來的事

Stack 支援那些操作呢

  • Push x - 把 x 塞到Stack的上面
  • Pop - 把 Stack 最上面的元素抽離
  • Top - 看看 Stack 最上面的元素是什麼
  • Clear - 把 Stack 清空

玩玩看 : https://www.cs.usfca.edu/~galles/visualization/StackArray.html

範例 - 自製Stack


[操作說明]

push x : 放入整數 x 進入stack

pop : 將stack中的整數拿出來

[input]

push 9
push 5
push 2
push 7
pop
pop
pop
push 1
pop
pop
pop

[output]

 pop: 7
 pop: 2
 pop: 5
 pop: 1
 pop: 9
 pop: nothing in stack

[說明]

  • 讓 stack_top 永遠等於最後一個元素的位置+1

  • 一開始 stack 中沒有任何元素,令 stack_top = 0

  • 當 stack 中沒有元素時就不能 pop

[Code]

#include<bits/stdc++.h>
using namespace std;

int stk[105], stack_top;


int main ()
{
    string cmd;
    int i;

    stack_top = 0;

    while( cin >> cmd ){
        if( cmd == "push" ){
            cin >> i;
            stk[stack_top] = i;
            stack_top++;
        }
        else if( cmd == "pop" ){
            if( stack_top == 0 )
                cout << " pop: nothing in stack" << endl;
            else{
                cout << " pop: " << stk[stack_top-1] << endl;
                stack_top--;
            }
        }
    }

    return 0;
}

[題目練習]

b923: stack 堆疊的模板題

https://zerojudge.tw/ShowProblem?problemid=b923

B304: Parentheses Balance

https://zerojudge.tw/ShowProblem?problemid=b304

解題要點:

  1. 一個字串變數負責存括號們
  2. 一個stack去把左括號存起來
  3. 碰到右括號的時候把stack的資料pop出來比對是否成對,沒成對代表"資料格式不對"
  4. 最後要取清算stack是否為空,沒空的話代表"資料格式不對"

解答:

#include<bits/stdc++.h>
#include <stack>
using namespace std;

int main(void){

    int n;
    string str;
    stack<int> stk;

    cin>>n;

    for(int i = 0 ;i<n;i++){

        cin>>str;
        bool pass = true;

        for(int j = 0 ;j<str.length();j++){

            if(str[j]=='('||str[j]=='['){
                stk.push( str[j] );
            }
            else if(stk.empty()){
                pass=false;
                break;
            }
            else if(str[j]==')'){
                if(stk.top()!='('){
                    pass=false;
                    break;
                }
                stk.pop();
            }
            else if(str[j]==']'){
                if(stk.top()!='['){
                    pass=false;
                    break;
                }
                stk.pop();
            }
        }

        if(!stk.empty()){
            pass = false;
        }

        if(pass==true)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;

    }

}

d016: 後序運算法

http://zerojudge.tw/ShowProblem?problemid=d016

輸入一個字串,並且取得長度與資料

#include <iostream>
#include <stack>
#include <sstream>

using namespace std;

int main(int argc, char *argv[]){
    string ins;
    int op1, op2, ans, i, j, k;
    stringstream ss;

    while(getline(cin, ins)){
        i = j = k = 0;
        stack<int>myStack;
        while(i<ins.length()){
            if(ins[i] >= '0' && ins[i] <= '9'){                   // 數字
                for(j=i+1; j<ins.length(); j++)               //找出所在區段
                    if(ins[j] == ' ')
                        break;
                string tmp = ins.substr(i, j-i);             //用substr抓出數字
                ss.str("");
                ss.clear();                                      //google到的結果說要這樣清空
                ss << tmp;
                ss >> op1;
                myStack.push(op1);
                i = j;
                i++;
            }
            else if(ins[i] == '+'){
                op2 = myStack.top();
                myStack.pop();
                op1 = myStack.top();
                myStack.pop();
                myStack.push(op1+op2);
                i+=2;
            }
            else if(ins[i] == '-'){
                op2 = myStack.top();
                myStack.pop();
                op1 = myStack.top();
                myStack.pop();
                myStack.push(op1-op2);
                i+=2;
            }
            else if(ins[i] == '*'){
                op2 = myStack.top();
                myStack.pop();
                op1 = myStack.top();
                myStack.pop();
                myStack.push(op1*op2);
                i+=2;
            }
            else if(ins[i] == '/'){
                op2 = myStack.top();
                myStack.pop();
                op1 = myStack.top();
                myStack.pop();
                myStack.push(op1/op2);
                i+=2;
            }
            else if(ins[i] == '%'){
                op2 = myStack.top();
                myStack.pop();
                op1 = myStack.top();
                myStack.pop();
                myStack.push(op1%op2);
                i+=2;
            }
        }
        cout<<myStack.top()<<endl;
    }

    return 0;
}

results matching ""

    No results matching ""