C++顺序栈解决括号的匹配问题

感觉对栈的理解有欠缺,搜索这道题的题解,发现有些代码不能切题的解决问题,有些代码显得高级但是过于复杂,没有合适方式的话就需要自己联想解决了。

我捡起了搁置一年的C语言知识,咱们来看下这个问题:

题目简介

简介:判断一个只包含:“{”、“[”、“(”、“)”、“]”、“}”括号的表达式中括号是否匹配,即从终端输入一个只包含以上几种括号的字符串,判断该字符串中的括号是否匹配。

要求:如该括号是左括号,则入栈,如果是右括号,则检测该括号是否与栈顶括号匹配。匹配前需要先判断栈中是否存在元素,如果有则用当前括号与栈顶的括号比较,如果匹配则继续遍历,否则返回匹配失败。

分部讲解

先聊一下这条题的整体思路,咱们想用栈,就必须有栈的结构,肯定希望拿到这个栈是全新的,所以需要对栈进行初始化,之后实现入栈和出栈,核心算法部分咱们分步分析。

下面咱们来看代码:

这几行可能有人很疑惑,这啥意思呀,简单来讲就是后面的代码可以用MAXSIZE来表示0,另外两个效果相同,这样更加符合语意需要,便于理解一块代码实现的功能。

定义一个栈的结构体,包含栈底指针,栈顶指针,还有栈的最大容量,上图箭头所指可以理解为这个结构体是SqStack类型的,后面可以直接用SqStack后跟变量来定义。

进行结构体的初始化,上图中&S表示将该结构体的址传递过来操作,后面再调用的话就是操作过的栈S,这里面用到了MAXSIZE代表实例化char数组的栈长为100,如果没分配到空间,S.base=null,如果null用来判断的话可以理解为false,!false=true,确保分配的栈不为空,将栈顶指针调成栈底。

上图代码用来判断是否栈空,如果栈底指针与栈顶指针相同,则栈为空,返回OK,如果栈非空,则返回ERROR,这里只需要进行判断的操作,所以只传递了栈值S。

入栈首先判断是否栈满,根据栈顶指针与栈底指针的差判断,如果栈未满,进行入栈操作,栈顶指针自加1,将新入栈的变量e赋予新的栈节点。

出栈需要判断是否栈空,栈顶指针自减之后将变化后的栈顶元素赋值给变量e。

获取栈顶元素的时候,只要栈不空,就可以返回栈顶指针减1获取栈顶元素值。

下面试核心代码部分

//括号匹配
int Confirm(char str[],int length){		
	SqStack S;
	InitStack(S);
	for(int i = 0;i<length ;i++){
		if(str[i] == '(' || str[i] == '[' || str[i] == '{'){
			Push(S,str[i]);		
		}else{
			if(IsEmpty(S)){			
				return ERROR;		
			}
			char topELem;
			Pop(S,topELem);		 
			if(str[i] == ')' && topELem != '(') {
				return ERROR;
			}
			if(str[i] == ']' && topELem != '[') {
				return ERROR;
			}
			if(str[i] == '}' && topELem != '{') {
				return ERROR;
			}
		} 
	}
	return IsEmpty(S);		
} 

接收输入的字符串和字符串长度,定义栈S并初始化栈,通过循环对字符串内容进行分辨,如果是左括号就用Push进行入栈操作,如果是右括号,先判断是否为空栈,因为必须有左括号之后,有右括号才能匹配,如果栈非空,则判断是否与出栈元素匹配,最后栈为空,说明全部匹配成功。

主函数代码如下:

int main()
{ 
	SqStack S;
	int a,b;
	printf("请输入字符串长度:");
	scanf("%d",&b);
	char str[b];
	printf("请输入字符串:");
	scanf("%s", &str);
	a = Confirm(str,b);
	if(a == 1) printf("匹配成功");
	else printf("false"); 
	return 0;
 } 

值得说一说的是定义的char数组,在用字符串进行输入的时候,前面应该用%s。

完整代码及思考

#include <stdio.h> 
#define MAXSIZE 10
#define ERROR 0;
#define OK 1;
 
typedef struct{
	char *base;
	char *top;
	int stacksize;
}SqStack;
 
 
// 1、初始化
void InitStack(SqStack &S){
	S.base=new char[MAXSIZE];
	if(!S.base) printf("储存分配失败");
	S.top=S.base;
	S.stacksize=MAXSIZE;
} 
 
// 2、判断栈空
int IsEmpty(SqStack S){
	if(S.top==S.base) return OK;
		return ERROR;
} 
 
// 3、入栈
int Push(SqStack &S,char e){
	if(S.top-S.base==S.stacksize)return ERROR;
	*S.top++=e;
	return OK;
} 
 
// 4、出栈
int Pop(SqStack &S,char &e){	
	if(S.top==S.base) return ERROR;
	e=*--S.top;
	return OK;
} 
 
// 5、读取栈顶元素
char GetTop(SqStack S){
	if(S.top!=S.base)
	return *(S.top-1);
} 
 
// 括号匹配
int Confirm(char str[],int length){		
	SqStack S;
	InitStack(S);
	for(int i = 0;i<length ;i++){
		if(str[i] == '(' || str[i] == '[' || str[i] == '{'){
			Push(S,str[i]);		
		}else{
			if(IsEmpty(S)){			
				return ERROR;		
			}
			char topELem;
			Pop(S,topELem);		 
			if(str[i] == ')' && topELem != '(') {
				return ERROR;
			}
			if(str[i] == ']' && topELem != '[') {
				return ERROR;
			}
			if(str[i] == '}' && topELem != '{') {
				return ERROR;
			}
		} 
	}
	return IsEmpty(S);		
} 
 
 
int main()
{ 
	SqStack S;
	int a,b;
	printf("请输入字符串长度:");
	scanf("%d",&b);
	char str[b];
	printf("请输入字符串:");
	scanf("%s", &str);
	a = Confirm(str,b);
	if(a == 1) printf("匹配成功");
	else printf("匹配失败"); 
	return 0;
 } 

总结的时候咱们用线性思维来看待这道题,解决的时候要面向每个点,一步一步走,平常回顾知识很有必要,夹生饭可不好吃呀。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值