當存儲的元素類型爲類類型,StaicStack 的對象在建立時會屢次調用元素類型的構造函數,影響效率!ios
文件:main.cpp算法
#include <iostream> #include "StaitcStack.h" using namespace std; using namespace DTLib; class Test : public Object { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { StaticStack<Test, 5> stack; cout << "stack.size() = " << stack.size() << endl; return 0; }
輸出:編程
Test() Test() stack.size() = 0 ~Test() ~Test() ~Test() ~Test() ~Test()
緣由:
T m_space[N];
- 類模板,抽象父類 Stack 的直接子類
- 在內部組合使用 LinkList 類,實現棧的鏈式存儲
- 只在單鏈表成員對象的頭部進行操做
文件:LinkStack.hide
#ifndef LINKSTACK_H #define LINKSTACK_H #include "Stack.h" #include "LinkList.h" #include "Exception.h" namespace DTLib { template <typename T> class LinkStack : public Stack<T> { public: void push(const T &e) override // O(1) { m_list.insert(0, e); } void pop() override // O(1) { if (m_list.length() > 0) { m_list.remove(0); } else { THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current LinkStack ..."); } } T top() const override // O(1) { if (m_list.length() > 0) { return m_list.get(0); } else { THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current LinkStack ..."); } } void clear() override // O(n) { m_list.clear(); } int size() const override // O(1) { return m_list.length(); } ~LinkStack() // O(n) { clear(); } protected: LinkList<T> m_list; }; } #endif // LINKSTACK_H
文件:main.cpp函數
#include <iostream> #include "LinkStack.h" using namespace std; using namespace DTLib; class Test : public Object { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { LinkStack<Test> stack_1; cout << "stack_1.size() = " << stack_1.size() << endl; cout << "-------" << endl; LinkStack<int> stack_2; for (int i=0; i<5; ++i) { stack_2.push(i); } while (stack_2.size() > 0) { cout << stack_2.top() << endl; stack_2.pop(); } return 0; }
輸出:spa
stack_1.size() = 0 ------- 4 3 2 1 0
在 C 語言中有一些成對匹配出現的符號
括號: (), [], {}, <>
引號: '', ""設計
問題: 如何實現編譯器中的符號成對檢測?
從第一字符開始掃描code
- 當碰見普通字符時忽略
- 當碰見左符號時壓入棧中
- 當碰見右符號時彈出棧頂符號,並進行匹配
結束對象
- 成功:全部字符掃描完畢,且棧爲空
- 失敗:匹配失敗或全部字符掃描完畢但棧非空
文件:main.cppblog
#include <iostream> #include "LinkStack.h" using namespace std; using namespace DTLib; bool is_left(char c) { return (c == '(') || (c == '{') || (c == '[') || (c == '<'); } bool is_right(char c) { return (c == ')') || (c == '}') || (c == ']') || (c == '>'); } bool is_quot(char c) { return (c == '\'') || (c == '\"'); } bool is_macth(char l, char r) { return ((l == '(') && (r == ')')) || ((l == '{') && (r == '}')) || ((l == '[') && (r == ']')) || ((l == '<') && (r == '>')) || ((l == '\'') && (r == '\'')) || ((l == '\"') && (r == '\"')); } bool scan(const char *code) { bool ret = true; int i = 0; LinkStack<char> stack; code = (code == nullptr) ? "" : code; while (ret && code[i] != '\0') { if (is_left(code[i])) { stack.push(code[i]); } else if (is_right(code[i])) { if ((stack.size() > 0) && is_macth(stack.top(), code[i])) { stack.pop(); } else { ret = false; } } else if (is_quot(code[i])) { if (stack.size() == 0 || !is_macth(stack.top(), code[i])) { stack.push(code[i]); } else if (is_macth(stack.top(), code[i])) { stack.pop(); } } ++i; } return ret && (stack.size() == 0); } int main() { cout << scan("<a{b(\'x\')c}d>") << endl; return 0; }
輸出:
1
- 鏈式棧的實現組合使用了單鏈表對象
- 在單鏈表的頭部進行操做可以實現高效的入棧和出棧操做
- 棧 「後進先出」 的特性適用於檢測成對出現的括號
- 棧很是適合於須要 「就近匹配」 的場合
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!