当存储的元素类型为类类型,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
- 链式栈的实现组合使用了单链表对象
- 在单链表的头部进行操做可以实现高效的入栈和出栈操做
- 栈 “后进先出” 的特性适用于检测成对出现的括号
- 栈很是适合于须要 “就近匹配” 的场合
以上内容整理于狄泰软件学院系列课程,请你们保护原创!