用栈检测括号匹配

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用栈检测括号匹配相关的知识,希望对你有一定的参考价值。

出现()[] 三种括号,嵌套时不允许出现交叉,且只能大括号嵌套中括号,中括号嵌套小括号,求代码~谢谢
中括号和大括号不允许单独出现

#include <stdio.h>
#include <string.h>

#define MaxSize 100

typedef char ElemType;//定义数据类型

//定义顺序栈
typedef struct

ElemType data[MaxSize];//数据域
int top;//栈顶指针
SeqStack;

//栈初始化
int InitStack(SeqStack *s)

s->top=-1;//初始化栈顶,指向空
return 1;


//入栈
int Push(SeqStack *s,ElemType x)

if (s->top == MaxSize -1 )

printf("栈已满,不能入栈.\n");
return 0;

else

s->top++;//栈顶指针上移
s->data[s->top] = x;//数据元素入栈

return 1;


//出栈
int Pop(SeqStack *s,ElemType *x)

if (s->top == -1)

printf("栈为空,不能出栈.\n");
return 0;

else

*x=s->data[s->top];//取出栈顶元素值
s->top--;//栈顶指针下移

return 1;


//取栈顶值
int GetTop(SeqStack *s,ElemType *x)

if (s->top == -1)

printf("栈为空,不能取值.\n");
return 0;

else

*x=s->data[s->top];//取出栈顶元素值

return 1;


//判断栈是否为空
int IsEmpty(SeqStack *s)

if(s->top==-1)
return 1;

return 0;


int Check(char str[],int len)

int i;
int flag=1;//合法标志0-不合法 1-合法
int exist=0;//小括号存在标志 0-不在 1-在
ElemType x;
SeqStack s;//栈s

//栈初始化
InitStack(&s);

for(i=0;i<len;i++)

if(str[i]=='')//大括号

if(IsEmpty(&s))//栈空,直接入栈

if(Push(&s,str[i])!=1)

flag=0;
break;


else//栈非空,判断合法性

if(GetTop(&s,&x)!=1)//取栈顶值

flag=0;
break;

if(x=='' || x=='[' || x== '(')//如果是,[或者(,非法

flag=0;
break;

else//否则入栈

if(Push(&s,str[i])!=1)

flag=0;
break;




else if(str[i]=='[')//方括号[

if(IsEmpty(&s))//栈空,直接入栈

if(Push(&s,str[i])!=1)

flag=0;
break;


else//栈非空,判断合法性

if(GetTop(&s,&x)!=1)//取栈顶值

flag=0;
break;

if(x=='[' || x== '(')//如果是[或者(,非法

flag=0;
break;

else//否则入栈

if(Push(&s,str[i])!=1)

flag=0;
break;




else if(str[i]=='(')//小括号(

//直接入栈
if(Push(&s,str[i])!=1)

flag=0;
break;

exist=1;//小括号存在

else if(str[i]==')')//小括号)

if(Pop(&s,&x)!=1)

flag=0;
break;

if(x!='(')//如果出栈非(,非法

flag=0;
break;


else if(str[i]==']')//方括号]

if(Pop(&s,&x)!=1)

flag=0;
break;

if(x!='[')//如果出栈非[,非法

flag=0;
break;

if(exist==0)//小括号不存在,单独[],非法

flag=0;
break;


else if(str[i]=='')//大括号

if(Pop(&s,&x)!=1)

flag=0;
break;

if(x!='')//如果出栈非,非法

flag=0;
break;

if(exist==0)//小括号不存在,单独[],非法

flag=0;
break;


else//其它字符跳过
continue;


if(!IsEmpty(&s))//循环完毕,栈非空,非法
flag=0;

return flag;


//主函数
int main(void)

char str[MaxSize];//录入字符串
int i,len;

while(1)

printf("输入字符串\n");
gets(str);
len=strlen(str);
if(len>=MaxSize)//超过定义长度
return 1;

if(Check(str,len)==1)
printf("匹配合法!\n");
else
printf("不合法\n");

printf("是否继续? 1-是,0否 :");
if(scanf("%d",&i)!=1 || i!=1)
break;
fflush(stdin);


return 0;
参考技术A #include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"process.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef char SElemType;
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量

struct SqStack

SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
; // 顺序栈

Status InitStack(SqStack &S)//申请一个空栈
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
S.top=S.base;
if(!S.base) return ERROR;
S.stacksize=STACK_INIT_SIZE;
return OK;


Status StackEmpty(SqStack S)//判断栈空
if(S.base==S.top) return TRUE;
else return FALSE;


Status Push(SqStack &S,SElemType e)//进栈

if(S.top-S.base>=S.stacksize)

S.base=(SElemType *)realloc(S.base,(STACK_INIT_SIZE+S.stacksize)*sizeof(SElemType));
if(!S.base) return ERROR;
S.top=S.base+S.stacksize;
S.stacksize=S.stacksize+STACK_INIT_SIZE;

*S.top=e;
S.top++;
return OK;


Status Pop(SqStack &S,SElemType &e)//出栈
if(S.base==S.top) return ERROR;
e=*--S.top;
return OK;


void check()
// 对于输入的任意一个字符串,检验括号是否配对
SqStack s;
int i;
i=0;
SElemType ch[80],*p,e;
if(InitStack(s)) // 初始化栈成功

printf("输入表达式:");
scanf("%s",ch);
p=ch;
while(*p) // 没到串尾
switch(*p)

case '(':
case '[':Push(s,*p);p++;i++;
break; // 左括号入栈,且p++
case ')':
case ']':if(!StackEmpty(s)) // 栈不空

Pop(s,e); // 弹出栈顶元素
if(*p==')'&&e!='('||*p==']'&&e!='[')
// 弹出的栈顶元素与*p不配对

printf("括号不配对\n");
exit(ERROR);

else

p++;
break; // 跳出switch语句


else // 栈空

printf("没有一个左括号\n配对不成功\n");
exit(ERROR);

default: p++; // 其它字符不处理,指针向后移

if(StackEmpty(s)) // 字符串结束时栈空
if(i==0)
printf("没有括号 不需要配对\n");
else printf("配对成功\n");

else
printf("没有一个右括号\n配对不成功\n");


void main()

check();

最长有效括号

https://leetcode-cn.com/problems/longest-valid-parentheses/

技术图片

思路

一开始的想法是用栈辅助匹配括号,后来发现题目中求的是最长有效,发现用栈直接匹配括号有点麻烦。后来,看了官方题解:

使用栈来记录最后一个没有被匹配的右括号的下标

  • 对于遇到的每个‘(‘,我们将它的下标放入栈中
  • 对于遇到的每个‘)‘,先弹出栈顶元素
    • 栈为空,将下标放入栈中
    • 栈不为空,i - stack.peek()即为以该右括号为结尾的最长有效括号的长度

既能满足匹配,又通过下标巧妙地求出最长有效的长度,这个想法很不错!

import java.util.Stack;

class Solution {
    public int longestValidParentheses(String s) {
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        stack.push(-1);
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == ‘(‘){
                stack.push(i);
            }
            else{
                stack.pop();
                if(stack.empty()){
                    stack.push(i);
                }
                else{
                    res = Math.max(res, i - stack.peek());
                }
            }
        }
        return res;
    }
}

以上是关于用栈检测括号匹配的主要内容,如果未能解决你的问题,请参考以下文章

Python 用栈判断括号匹配

Java 栈 如何实现括号匹配

20. Valid Parentheses(用栈实现括号匹配)

最长有效括号

c语言关于栈中内存无法使用的问题

32. Longest Valid Parentheses