Computer-Science

1. Stack

STL Stack

μŠ€νƒ 객체λ₯Ό μ„ μ–Έν•˜κΈ° μœ„ν•΄μ„œλŠ” β€œstack”이라고 λΆˆλ¦¬λŠ” μ •μ˜ νŒŒμΌμ„ λ¨Όμ € 포함해야 ν•œλ‹€. STL 벑터 ν΄λž˜μŠ€μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ μŠ€νƒ ν΄λž˜μŠ€λ„ std λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— ν¬ν•¨λ˜κΈ° λ•Œλ¬Έμ— std::stack으둜 μ‚¬μš©ν•˜λ˜μ§€ using문을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. 예λ₯Ό λ“€μ–΄, λ‹€μŒ ν”„λ‘œκ·Έλž¨μ€ μ •μˆ˜μ˜ μŠ€νƒμ„ μ„ μ–Έν•œλ‹€.

#include <stack>
using std::stack    // stack을 μ ‘κ·Όν•  수 있게 ν•œλ‹€.
stack<int> myStack; // μ •μˆ˜μ˜ μŠ€νƒ

μŠ€νƒ μ—°μ‚°μ˜ 우리 μ •μ˜μ™€ STL κ΅¬ν˜„μ˜ μ€‘μš”ν•œ 차이가 μžˆλ‹€. STL κ΅¬ν˜„μ—λŠ” μ€‘μš”ν•œ 차이가 있자. STL κ΅¬ν˜„μ—λŠ” 빈 μŠ€νƒμ— λŒ€ν•œ top λ˜λŠ” pop μ—°μ‚°μ˜ κ²°κ³Όκ°€ μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. 즉, 였λ₯˜(exception)κ°€ λ°œμƒλ˜μ§€ μ•ŠλŠ”λ‹€. 였λ₯˜κ°€ λ°œμƒλ˜μ§€ μ•Šλ”λΌλ„, λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ΄ 쀑단될 κ°€λŠ₯성이 λ†’λ‹€. λ”°λΌμ„œ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ κ·ΈλŸ¬ν•œ λΆˆλ²•μ μΈ 접근을 ν•˜μ§€ μ•ŠλŠ” 것이 ν•„μš”ν•˜λ‹€.

Stack Interface in C++

// An informal Stack interface(not a complete C++ class)

template <typename E>
class Stack
{
public:
    int size() const;
    bool empty() const;
    const E &top() const throw(StackEmpty);
    void push(const E &e);
    void pop() throw(StackEmpty);
}

Array-based Stack in C++

#include <iostream>
#include <string>
using namespace std;

// Code Fragment 2.4: RuntimeException
class RuntimeException
{ // generic run-time exception
private:
    string errorMsg;

public:
    RuntimeException(const string &err) { errorMsg = err; }
    string getMessage() const { return errorMsg; }
};

// Code Fragment 5.2: Exception thrown by functions pop and top when called on an empty stack.
// Exception thrown on performing top or pop of an empty stack.
class StackEmpty : public RuntimeException
{
public:
    StackEmpty(const string &err) : RuntimeException(err) {}
};

class StackFull : public RuntimeException
{
public:
    StackFull(const string &err) : RuntimeException(err) {}
};

// Code Fragment 5.1: An informal Stack interface (not a complete C++ class).
template <typename E>
class Stack
{ // an interface for a stack
public:
    int size() const;                       // number of items in stack
    bool empty() const;                     // is the stack empty?
    const E &top() const throw(StackEmpty); // the top element
    void push(const E &e);                  // push x onto the stack
    void pop() throw(StackEmpty);           // remove the top element
};

// Code Fragment 5.4 : The class ArrayStack, which implements the Stack interface.
template <typename E>
class ArrayStack
{
    enum
    {
        DEF_CAPACITY = 100
    }; // default stack capacity
public:
    ArrayStack(int cap = DEF_CAPACITY);     // constructor from capacity
    int size() const;                       // number of items in the stack
    bool empty() const;                     // is the stack empty?
    const E &top() const throw(StackEmpty); // get the top element
    void push(const E &e) throw(StackFull); // push element onto stack
    void pop() throw(StackEmpty);           // pop the stack
    // . . .housekeeping functions omitted
private:          // member data
    E *S;         // array of stack elements
    int capacity; // stack capacity
    int t;        // index of the top of the stack
};

// Code Fragment 5.5: Implementations of the member functions of class ArrayStack (excluding housekeeping functions).
template <typename E>
ArrayStack<E>::ArrayStack(int cap)
    : S(new E[cap]), capacity(cap), t(-1) {} // constructor from capacity
template <typename E>
int ArrayStack<E>::size() const
{
    return (t + 1);
} // number of items in the stack
template <typename E>
bool ArrayStack<E>::empty() const
{
    return (t < 0);
} // is the stack empty?
template <typename E> // return top of stack
const E &ArrayStack<E>::top() const throw(StackEmpty)
{
    if (empty())
        throw StackEmpty("Top of empty stack");
    return S[t];
}
template <typename E> // push element onto the stack
void ArrayStack<E>::push(const E &e) throw(StackFull)
{
    if (size() == capacity)
        throw StackFull("Push to full stack");
    S[++t] = e;
}
template <typename E> // pop the stack
void ArrayStack<E>::pop() throw(StackEmpty)
{
    if (empty())
        throw StackEmpty("Pop from empty stack");
    --t;
}

int main()
{
    // Code Fragment 5.6 : An example of the use of the ArrayStack class.
    // The contents of the stack are shown in the comment following the operation.
    // The top of the stack is indicated by an asterisk (β€œ*”).
    ArrayStack<int> A; // A = [ ], size = 0
    A.push(7);         // A = [7*], size = 1
    A.push(13);        // A = [7, 13*], size = 2
    cout << A.top() << endl;
    A.pop();                 // A = [7*], outputs: 13
    A.push(9);               // A = [7, 9*], size = 2
    cout << A.top() << endl; // A = [7, 9*], outputs: 9
    cout << A.top() << endl;
    A.pop();                  // A = [7*], outputs: 9
    ArrayStack<string> B(10); // B = [ ], size = 0
    B.push("Bob");            // B = [Bob*], size = 1
    B.push("Alice");          // B = [Bob, Alice*], size = 2
    cout << B.top() << endl;
    B.pop();       // B = [Bob*], outputs: Alice
    B.push("Eve"); // B = [Bob, Eve*], size = 2
}

Stack with a Singly-linked List

SinglyLinkedList.h

#include <string>
using std::string;

// Code Fragment 3.18: A node in a generic singly linked list.
template <typename E>
class SNode
{ // singly linked list node
private:
    E elem;                      // linked list element value
    SNode<E> *next;              // next item in the list
    friend class SLinkedList<E>; // provide SLinkedList access
};

// Code Fragment 3.19: A class definition for a generic singly linked list.
template <typename E>
class SLinkedList
{ // a singly linked list
public:
    SLinkedList();             // empty list constructor
    ~SLinkedList();            // destructor
    bool empty() const;        // is list empty?
    const E &front() const;    // return front element
    void addFront(const E &e); // add to front of list
    void removeFront();        // remove front item list
private:
    SNode<E> *head; // head of the list
};

// Code Fragment 3.20: Other member functions for a generic singly linked list.
template <typename E>
SLinkedList<E>::SLinkedList() // constructor
    : head(NULL)
{
}
template <typename E>
bool SLinkedList<E>::empty() const // is list empty?
{
    return head == NULL;
}
template <typename E>
const E &SLinkedList<E>::front() const // return front element
{
    return head->elem;
}
template <typename E>
SLinkedList<E>::~SLinkedList() // destructor
{
    while (!empty())
        removeFront();
}
template <typename E>
void SLinkedList<E>::addFront(const E &e)
{                               // add to front of list
    SNode<E> *v = new SNode<E>; // create new node
    v->elem = e;                // store data
    v->next = head;             // head now follows v
    head = v;                   // v is now the head
}
template <typename E>
void SLinkedList<E>::removeFront()
{                         // remove front item
    SNode<E> *old = head; // save current head
    head = old->next;     // skip over old head
    delete old;           // delete the old head
}

Stack_with_a_Singly-linked_List.cpp

#include <iostream>
#include <string>
#include "SinglyLinkedList.h"
using namespace std;

// Code Fragment 2.4: RuntimeException
class RuntimeException
{ // generic run-time exception
private:
    string errorMsg;

public:
    RuntimeException(const string &err) { errorMsg = err; }
    string getMessage() const { return errorMsg; }
};

// Code Fragment 5.2: Exception thrown by functions pop and top when called on an empty stack.
// Exception thrown on performing top or pop of an empty stack.
class StackEmpty : public RuntimeException
{
public:
    StackEmpty(const string &err) : RuntimeException(err) {}
};

class StackFull : public RuntimeException
{
public:
    StackFull(const string &err) : RuntimeException(err) {}
};

Applications of Stacks

Parentheses Matching Algorithm

κ΄„ν˜Έκ²€μ‚¬ μŠ€νƒμ„ μ‚¬μš©ν•˜μ—¬ μˆ˜μ‹μ˜ κ΄„ν˜Έ μ‚¬μš©μ΄ μ˜¬λ°”λ₯Έμ§€ 확인할 수 μžˆλ‹€. κ΄„ν˜Έμ—λŠ” μ„Έ μ’…λ₯˜κ°€ μžˆλ‹€ β€˜()’, β€˜{}’, β€˜[]’ μ—¬λŠ” κ΄„ν˜Έλ₯Ό μ™Όμͺ½, λ‹«λŠ” κ΄„ν˜Έλ₯Ό 였λ₯Έμͺ½μ΄λΌ ν‘œν˜„ν•˜κ² λ‹€.

bool ParenMatch(char X[])
{
	int i = 0; prev;
    char ch;

    while(X[i] != '\0')
    {
    	ch = X[i++];;
        if(ch == '[' || ch =='{' || ch == '(') push(ch);
        else if (ch == ']' || ch == '}' || ch ++ ')')
        {
        	if(empty()) return false;
            prev = top();
            pop();
            if((ch == ']' && prev != '[')
            || (ch == '}' && prev != '{')
            || (ch == ')' && prev != '('))
            	return false;
        }
    }
    if (empty()) return false;

    return true;
}