栈常考应用之括号匹(C++)
阅读原文时间:2023年07月10日阅读:1

思路在注释里。还是使用链栈的API,为啥使用链栈呢,因为喜欢链栈。

//header.h
#pragma once
#include
using namespace std;
template
struct LinkNode //节点类定义
{
T data; //数据域
LinkNode *next; //链指针域
LinkNode(LinkNode *ptr = NULL){this->next = ptr;} //初始化指针域的构造函数
LinkNode(const T& item, LinkNode *ptr = NULL)//初始化数据成员和指针成员和指针的构造函数
{
this->data = item;
this->next = ptr;
}
};

template
class ListStack //用头结点的数据域表示链表元素数量
{
protected:
LinkNode *first;
public:
ListStack(){first = new LinkNode;first->data = 0;}//无参数构造
ListStack(const T& x)
{
this->first = new LinkNode;
this->input(x);
}//含有参数的构造函数
ListStack(ListStack& L);//拷贝构造
~ListStack(){makeEmpty();}//析构函数
void makeEmpty();//将链表置空的函数
int Length()const{return this->first->data;}//计算链表长度的函数
LinkNode* getHead()const{return this->first;}//返回附加头结点地址
LinkNode* getRear()const;//返回尾部指针
void input(T head);//头插
void output();//将链表打印出来
bool Remove(int i, T& x);
bool IsEmpty()const{return !this->first->data;}
bool outstack(T& x);

};
template
bool ListStack::outstack(T& x)
{
return this->Remove(1, x);
}
template
bool ListStack::Remove(int i, T& x)
{
if(i>0 && i<=this->first->data)
{
LinkNode *tmp = this->first, *p;
if(i!=1)
{
int j = 0;
while(j!=i-1)
{
tmp = tmp->next;
++j;
}
p = tmp->next;
tmp->next = p->next;
x = p->data;
delete p;
}
else
{
p = tmp->next;
x = p->data;
tmp->next = p->next;
delete p;
}
--this->first->data;
return true;
}
return false;
}

template
void ListStack::input(T head)
{
LinkNode *tmp = new LinkNode;
if(tmp == NULL)
{
cerr<<"内存分配错误!\n"<<endl;
exit(-1);
}

if(this->first->next != NULL)  
{  
    tmp->next = this->first->next;  
    this->first->next = tmp;  
}  
else  
{  
    this->first->next = tmp;  
    tmp->next = NULL;  
}  
tmp->data = head;  
++this->first->data;

}
template
void ListStack::output()
{
LinkNode *p = this->first->next;
while(p!=NULL)
{
cout<data<<" | "; p = p->next;
}
cout<<"over"<
ListStack::ListStack(ListStack& L)
{
T value;
LinkNode *srcptr = L.getHead();
LinkNode *desptr = this->first = new LinkNode;
this->first->data = srcptr->data;
while(srcptr->next != NULL)
{
value = srcptr->next->data;
desptr->next = new LinkNode(value);
desptr = desptr->next;
srcptr = srcptr->next;
}
desptr->next = NULL;
}
template
void ListStack::makeEmpty()
{
LinkNode *p, *q = this->first->next;
this->first->data = 0;
while(q != NULL)
{
p = q;
q = q->next;
delete p;
}
}
template
LinkNode* ListStack::getRear()const
{
LinkNode *p = this->first;
while(p->next!=NULL)
p = p->next;
return p;

}
/*
template
int List::Length()const
{
LinkNode *p = this->first->next;
int count = 0;
while(p != NULL)
{
++count;
p = p->next;
}

};*/
//template

仅是将链栈的del函数修改为outstack

思路如下

#include"header.h"
//设计思路,首先是一个大循环①,匹配到左括号都让其进栈②,一旦入栈发现是右括号,出栈一个括号,检查左右是否匹配,不匹配则匹配失败③,若匹配成功继续入栈④,若无元素可入栈,检测栈空否⑤,空则匹配成功,否则匹配失败
bool match(const char *p)
{
ListStack st;
char outchar;
int i = 0;
while(p[i]!='\n')//①
{
switch(p[i])
{
case '('://②
st.input(p[i]);
++i;
break;
case '['://②
st.input(p[i]);
++i;
break;
case '{'://②
st.input(p[i]);
++i;
break;
case '<'://② st.input(p[i]); ++i; break; case ')'://③④ st.outstack(outchar); if(outchar == '(') { ++i; continue; } return false; case ']'://③④ st.outstack(outchar); if(outchar == '[') { ++i; continue; } return false; case '}'://③④ st.outstack(outchar); if(outchar == '{') { ++i; continue; } return false; case '>'://③④
st.outstack(outchar);
if(outchar == '<')
{
++i;
continue;
}
return false;
default:
++i;
continue;

    }  
}  
if(st.IsEmpty())//⑤  
    return true;  
return false;  

}
int main()
{
const char *p = "(0+1)*{7/2}-[6%7]<>";
if(match(p))
cout<<p<<" 匹配成功!"<<endl;
else
cout<<p<<" 匹配失败!"<<endl;
return 0;
}

本来打算使用主函数传参将括号字符串传入函数,但是由于主函数参数不能为()和{}

如果我用主函数参数传参则

用了两个字符串来试试

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章