第三十五课 栈的概念及实现(下)
自定义Test类,给出如下的测试程序:
1 #include <iostream> 2 #include "StaticStack.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 class Test : public Object 8 { 9 public: 10 Test() 11 { 12 cout << "Test()" << endl; 13 } 14 15 ~Test() 16 { 17 cout << "~Test()" << endl; 18 } 19 }; 20 21 int main() 22 { 23 StaticStack<Test, 10> stack; 24 25 cout << stack.size() << endl; 26 27 return 0; 28 }
运行结果如下:
此时栈中没有任何元素,却调用了10次构造函数和10次析构函数。
这是因为我们使用了原生数组作为存储空间,在创建栈的时候,当然会调用泛指类型T的构造函数。
我们需要另一种存储形式,来避免这种缺陷。
添加LinkStack.h文件:
1 #ifndef LINKSTACK_H 2 #define LINKSTACK_H 3 4 #include "Stack.h" 5 #include "LinkList.h" 6 7 8 namespace DTLib 9 { 10 11 template < typename T > 12 class LinkStack : public Stack<T> 13 { 14 protected: 15 LinkList<T> m_list; 16 public: 17 void push(const T& e) 18 { 19 m_list.insert(0, e); 20 } 21 22 void pop() 23 { 24 if( m_list.length() > 0 ) 25 { 26 m_list.remove(0); 27 } 28 else 29 { 30 THROW_EXCEPTION(InvalidOperationException, "No element in current stack..."); 31 } 32 } 33 34 T top() const 35 { 36 if( m_list.length() > 0 ) 37 { 38 return m_list.get(0); 39 } 40 else 41 { 42 THROW_EXCEPTION(InvalidOperationException, "No element in current stack..."); 43 } 44 } 45 46 void clear() 47 { 48 m_list.clear(); 49 } 50 51 int size() const 52 { 53 return m_list.length(); 54 } 55 56 }; 57 58 } 59 60 #endif // LINKSTACK_H
测试程序如下:
1 #include <iostream> 2 #include "LinkStack.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 class Test : public Object 8 { 9 public: 10 Test() 11 { 12 cout << "Test()" << endl; 13 } 14 15 ~Test() 16 { 17 cout << "~Test()" << endl; 18 } 19 }; 20 21 int main() 22 { 23 LinkStack<Test> stack; 24 25 cout << stack.size() << endl; 26 27 return 0; 28 }
结果如下:
没有再调用构造函数。
栈的应用实践:
问题:
如何实现编译器中的符号成对检测?
程序如下:
1 #include <iostream> 2 #include "LinkStack.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 bool is_left(char c) 8 { 9 return (c == '(') || (c == '{') || (c == '[') || (c == '<'); 10 } 11 12 bool is_right(char c) 13 { 14 return (c == ')') || (c == '}') || (c == ']') || (c == '>'); 15 } 16 17 bool is_quot(char c) 18 { 19 return (c == '\'') || (c == '\"'); 20 } 21 22 bool is_match(char l, char r) 23 { 24 return ( (l == '(') && (r == ')') ) || 25 ( (l == '{') && (r == '}') ) || 26 ( (l == '[') && (r == ']') ) || 27 ( (l == '<') && (r == '>') ) || 28 ( (l == '\'') && (r == '\'') ) || 29 ( (l == '\"') && (r == '\"') ); 30 } 31 32 bool scan(const char* code) 33 { 34 LinkStack<char> stack; 35 int i = 0; 36 bool ret = true; 37 38 code = (code == NULL) ? "" : code; 39 40 while( ret && (code[i] != '\0') ) 41 { 42 if( is_left(code[i]) ) 43 { 44 stack.push(code[i]); 45 } 46 else if( is_right(code[i]) ) 47 { 48 //右字符且此时栈大小为0(即认为不匹配),则匹配失败 49 if( (stack.size() > 0) && is_match(stack.top(), code[i]) ) 50 { 51 stack.pop(); 52 } 53 else 54 { 55 ret = false; 56 } 57 } 58 else if( is_quot(code[i]) ) // 引号单独处理 59 { 60 //如果栈是空的或者当前的引号是左字符(也就是和栈顶不匹配),则入栈 61 if( stack.size() == 0 || !is_match(stack.top(), code[i]) ) 62 { 63 stack.push( code[i] ); 64 } 65 else if( is_match(stack.top(), code[i]) ) //如果匹配,则栈顶出栈 66 { 67 stack.pop(); 68 } 69 } 70 71 i++; 72 } 73 74 return ret && (stack.size() == 0); 75 } 76 77 int main() 78 { 79 cout << scan("<a{b(\'x\')c}d>") << endl; 80 81 return 0; 82 }
结果如下:
测试程序2:
1 #include <iostream> 2 #include "LinkStack.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 bool is_left(char c) 8 { 9 return (c == '(') || (c == '{') || (c == '[') || (c == '<'); 10 } 11 12 bool is_right(char c) 13 { 14 return (c == ')') || (c == '}') || (c == ']') || (c == '>'); 15 } 16 17 bool is_quot(char c) 18 { 19 return (c == '\'') || (c == '\"'); 20 } 21 22 bool is_match(char l, char r) 23 { 24 return ( (l == '(') && (r == ')') ) || 25 ( (l == '{') && (r == '}') ) || 26 ( (l == '[') && (r == ']') ) || 27 ( (l == '<') && (r == '>') ) || 28 ( (l == '\'') && (r == '\'') ) || 29 ( (l == '\"') && (r == '\"') ); 30 } 31 32 bool scan(const char* code) 33 { 34 LinkStack<char> stack; 35 int i = 0; 36 bool ret = true; 37 38 code = (code == NULL) ? "" : code; 39 40 while( ret && (code[i] != '\0') ) 41 { 42 if( is_left(code[i]) ) 43 { 44 stack.push(code[i]); 45 } 46 else if( is_right(code[i]) ) 47 { 48 //右字符且此时栈大小为0(即认为不匹配),则匹配失败 49 if( (stack.size() > 0) && is_match(stack.top(), code[i]) ) 50 { 51 stack.pop(); 52 } 53 else 54 { 55 ret = false; 56 } 57 } 58 else if( is_quot(code[i]) ) // 引号单独处理 59 { 60 //如果栈是空的或者当前的引号是左字符(也就是和栈顶不匹配),则入栈 61 if( stack.size() == 0 || !is_match(stack.top(), code[i]) ) 62 { 63 stack.push( code[i] ); 64 } 65 else if( is_match(stack.top(), code[i]) ) //如果匹配,则栈顶出栈 66 { 67 stack.pop(); 68 } 69 } 70 71 i++; 72 } 73 74 return ret && (stack.size() == 0); 75 } 76 77 int main() 78 { 79 cout << scan("else if( is_quot(code[i]) ){if( stack.size() == 0 || \ 80 !is_match(stack.top(), code[i]) ) {stack.push( code[i] ); \ 81 }else if( is_match(stack.top(), code[i]) ){stack.pop();}}" \ 82 ) << endl; 83 84 return 0; 85 }
我们测试的是一段C++的代码,结果依然输出1。
小结: