我们要做的是,对一个字符串的左右括号进行匹配。例如,字符串(a*(b+c)+d)这个字符串的括号就是匹配的,没有多余的左括号或右括号。 这是数据结构中的一类很经典的问题。
对于这个问题,思路上要正确。如果从左至右的扫描一个字符串,那么每一个右括号都和都与最近扫描的那个未匹配的左括号相匹配。这种观察结果促使我们在在从左至右的扫描的过程中,将扫描到的左括号都存在栈中,。每当扫描到一个右括号,就将它与栈顶的左括号相匹配(如果存在),并将匹配的左括号从栈中删除。
虽然现在C++中有现成的stack类可以供我们直接使用,但是我们必须要明白其中背后的工作原理。所以我给出的是没有使用stack类的代码(纯原创) 下面展示一些 内联代码片。
int main() { int size = 0; Node<char> *head,*p; char a[10]; for(int i = 0;i<10;i++) { cin>>a[i]; } for(int i = 0;i<10;i++) { if(a[i] == '(') { if(size == 0) { head = new Node<char> ; p = head; p->element = a[i]; size++; cout<<size<<endl; } else if(size != 0) { p->next = new Node<char>(a[i]) ; p = p->next; size++; cout<<size<<endl; } } else if(a[i] == ')') { Node<char>* SearchPoint = head; for(int j = 0;j < size-1;j++) { SearchPoint = SearchPoint->next; } delete SearchPoint; size--; cout<<size<<endl; } } if(size == 0) { cout<<"hahaha成功了"; } else if (size != 0) { cout<<"没成功"; } }在这个办法中,其实更偏向于C的一些用法和思路(因为C++里有直接可以使用的类嘛,所以我就根据思路自己写出来的类stack的背后工作原理)。主要展示的是入栈(压栈),出栈操作。
第二种解决方法其实就是模仿STL中的stack类,自己写出一个stack类,并且使用它。因为会用到类,所以这个方法比上一个方法的代码体量更大。但是这个方法只有可扩展性的,即我们可以在此基础上增添操作等。
#include<iostream> using namespace std; template<class T> struct Node { T element; Node<T>* next; Node(){ } Node(T& element) { this->element = element; } Node(Node<T>* next) { this->next = next; } }; template<class T> class stackList { private: Node<T>* firstNode; int size ; public: stackList(){ } stackList(int size,Node<T>* firstNode); bool empty(); void insertfunction(T element,Node<T>* head,Node<T>* p); void popfunction(Node<T>* head); ~stackList(){ } }; template<class T> void stackList<T>::popfunction(Node<T>* head) { Node<char>* SearchPoint = head; for(int j = 0;j < size-1;j++) { SearchPoint = SearchPoint->next; } cout<<"111111111111111"<<endl; size--; cout<<size<<endl; SearchPoint = NULL; delete SearchPoint; } template<class T> void stackList<T>::insertfunction(T element,Node<T>* head,Node<T>* p) { if(size == 0) { head = new Node<char> ; p = head; p->element = element; size++; cout<<size<<endl; } else if(size != 0) { p->next = new Node<char>(element) ; p = p->next; size++; cout<<size<<endl; } } template<class T> stackList<T>::stackList(int size,Node<T>* firstNode) { this->size = size; this->firstNode = firstNode; } template<class T> bool stackList<T>::empty() { if(size == 0) { return true; } else return false; } int main() { Node<char> *head,*p; head = new Node<char> ; p = head; stackList<char> m (0,p); char a[10]; for(int i = 0;i<10;i++) { cin>>a[i]; } for(int i = 0;i<10; i++) { if(a[i] == '(') { m.insertfunction(a[i],head,p); } else if(a[i] == ')') { m.popfunction(head); } } if(m.empty() == true) { cout<<"成功了"<<endl; } else if(m.empty() == false) { cout<<"试败了"<<endl; } }下面来讲一下,这个办法的话它其实就是从上面的方法派生出来额。有一个点我在写代码的时候卡了很久。就是 template void stackList::popfunction(Node* head) { Node* SearchPoint = head; for(int j = 0;j < size-1;j++) { SearchPoint = SearchPoint->next; } cout<<“111111111111111”<<endl; size–; cout<<size<<endl; SearchPoint = NULL;---------------1 delete SearchPoint;-----------------2 } 这个函数中最后如果把1和2位置调换的话,整个程序是有问题的, delete SearchPoint这一步会卡住,走不动了。后面的程序就无法执行。如果按照上述顺序则没有任何问题。这个问题我卡了很久,但是至于原因我还没有找到,只找到了解决办法。如果有小伙伴晓得原理,欢迎评论区留言哈。