考研数据结构之栈(2.3)——练习题之判断表达式中的括号是否正确配对(C表示)

题目

C语言中算术表达式中的括号只有小括号。编写算法,判断一个表达式中的括号是否正确配对,表达式已经存入字符数组exp[]中,表达式的字符个数为n。

分析

本题可以用栈来解决,下面就来说说为什么要用栈来解决。

给你一个表达式,目测怎么判断括号是否匹配呢?可以这样做,从左往右看这个表达式中的括号,看到一个“(“就记住它(这里可以理解为入栈),如果下一个括号是“)”(这里可以理解为出栈),则划掉这两个括号,一对括号处理完毕继续往后看。如果前边所有的括号都被划掉,而下一个括号却是“)”,则括号一定不匹配,因为“)”之前已经没有括号和它匹配了。如果下一个括号是“(",则暂时不管前一个“(”,先把它放在那里,等后边的“(”处理掉后再来处理它。后边的“("处理掉才能回来处理先前的“(",这里体现了栈的先进后出特点。以后看到的括号要么是“(",要么是“)”,就用前边的方法来处理。如果到最后所有括号都被划掉,则匹配,否则就不匹配。由此可见,一个问题中如果出现诸如这种情况,即在解决问题的过程中出现了一个子问题,但凭现有条件不能解决它,需要记下,等待以后出现可以算决它的条件后再返回来解决。这种问题需要用栈来解决,栈具有记忆的功能,这是栈的FILO特性所延伸出来的一种特性。

注意是顺序栈,这里是用链栈的方式演示了配对括号的过程。

代码

配对的核心代码:

/* 用来比较括号是否正确配对,如果正常配对返回1,否则返回0 */
/* exp[]指的是括号表达式数组,是字符型的;n指的是数组元素个数 */ 
int match(char exp[],int n){
	/* 初始化顺序栈 */ 
	SqStack stack;// 定义一个顺序栈 
	char x;// 定义一个放出栈元素的变量 
	initStack(stack);// 调用函数初始化顺序栈 
	/* 判断表达式的括号是否匹配 */ 
	for(int i=0;i<n;i++){// 循环遍历数组中的每个括号 
		if(exp[i]=='('){// 判断括号是不是'(',如果是的话 
			push(stack,exp[i]);// 则压入顺序栈 
		}
		if(exp[i]==')'){// 判断括号是不是')',如果是的话 
			if(isEmpty(stack)==1){// 如果当前遇到的括号是")",并且栈已空,则不匹配,返回0 
				return 0;
			}else{ // 如果栈不空,则出栈。也就是划掉"()" 
				pop(stack,x);
			}
		} 
	}
	/* 循环遍历括号表达式完毕后,对结果进行反馈 */ 
	if(isEmpty(stack)==1){// 如果栈空的话,即所有括号都正确配对,返回1 
		return 1;
	}else{// 如果栈不空,则栈中存在着"(",故未能正确配对,返回0 
		return 0;
	}
} 

完整代码如下:

#include <stdio.h>
 
#define maxSize 20
 
typedef struct {
	char data[maxSize];// 存放栈中元素,maxSize是已经定义好的常量
	int top;// 栈顶指针
} SqStack; // 顺序栈类型定义
 
/* 初始化顺序栈 */
/* &st指的是要操作的顺序栈 */
void initStack(SqStack &st) {
	st.top=-1; // 只需将栈顶指针设置为-1,本栈中将top=-1规定为栈空状态
}
 
/* 判断栈空 */
/* st指的是要进行判空的顺序栈 */
int isEmpty(SqStack st) {
	// 栈为空的时候返回1,否则返回0
	if(st.top==-1) { // 判空的条件是栈顶指针是否等于-1
		return 1;
	} else {
		return 0;
	}
}
 
/* 判断栈满 */
/* st指的是要进行判满的顺序栈 */
int isFull(SqStack st) {
	// 如果栈顶指针等于maxSize-1那么栈满,否则栈空
	if(st.top==maxSize-1) { // maxSize是栈中最大元素个数,已经定义
		return 1;// 栈满返回1
	} else {
		return 0;// 栈空返回0
	}
}
 
/* 进栈 */
/* &st指的是要操作的栈;x指的是要进栈的数据 */
int push(SqStack &st,char x) {
	/* 进栈首先要判断栈是否栈满,如果满栈则不能进栈 */
	if(isFull(st)==1) {
		return 0;// 如果栈满返回0,表示不能进栈
	} else {
		// 注意:++top和top++在这里的作用是一样的,都可以使用,如果是a=++top和a=top++,那么两个a的值是不一样的,最后top的值还是一样
		++st.top;// 先移动指针,再进栈
		st.data[st.top]=x;
		return 1;// 进栈成功返回1
	}
}
 
/* 出栈 */
/* &st指的是要操作的栈;&x指的是要出栈的数据 */
int pop(SqStack &st,char &x) {
	/* 出栈之前要判断栈是否为空 */
	if(isEmpty(st)==1) {// 1表示栈空,0表示非空
		return 0;// 如果栈空,不能出栈,返回0
	} else {
		x=st.data[st.top];// 先取出元素,再出栈
		--st.top;
		return 1;// 出栈成功返回1
	}
}
 
/* 打印栈,从左到右表示栈底到栈顶 */
/* stack表示要被打印的栈 */
void printStack(SqStack stack) {
	printf("\n");
	for(int i=0; i<=stack.top; i++) {// 注意:data[0]表示栈底元素,data[top]表示栈顶元素
		printf("%c\t",stack.data[i]);// 打印栈中元素
	}
	printf("\n");
}

/* 用来比较括号是否正确配对,如果正常配对返回1,否则返回0 */
/* exp[]指的是括号表达式数组,是字符型的;n指的是数组元素个数 */ 
int match(char exp[],int n){
	/* 初始化顺序栈 */ 
	SqStack stack;// 定义一个顺序栈 
	char x;// 定义一个放出栈元素的变量 
	initStack(stack);// 调用函数初始化顺序栈 
	/* 判断表达式的括号是否匹配 */ 
	for(int i=0;i<n;i++){// 循环遍历数组中的每个括号 
		if(exp[i]=='('){// 判断括号是不是'(',如果是的话 
			push(stack,exp[i]);// 则压入顺序栈 
		}
		if(exp[i]==')'){// 判断括号是不是')',如果是的话 
			if(isEmpty(stack)==1){// 如果当前遇到的括号是")",并且栈已空,则不匹配,返回0 
				return 0;
			}else{ // 如果栈不空,则出栈。也就是划掉"()" 
				pop(stack,x);
			}
		} 
	}
	/* 循环遍历括号表达式完毕后,对结果进行反馈 */ 
	if(isEmpty(stack)==1){// 如果栈空的话,即所有括号都正确配对,返回1 
		return 1;
	}else{// 如果栈不空,则栈中存在着"(",故未能正确配对,返回0 
		return 0;
	}
} 
 
int main() {
	int result;
	
	char exp[]={'(',')','(','(',')'};
	result=match(exp,5);
	printf("是否匹配(1表示正确配对,0表示错误配对):%d",result);	

	return 0;
}

测试效果:

简化栈操作的代码:

#include <stdio.h>
 
#define maxSize 20

/* 用来比较括号是否正确配对,如果正常配对返回1,否则返回0 */
/* exp[]指的是括号表达式数组,是字符型的;n指的是数组元素个数 */ 
int match(char exp[],int n){
	/* 初始化顺序栈,简化操作 */ 
	char stack[maxSize]; 
	int top=-1;
	/* 判断表达式的括号是否匹配 */ 
	for(int i=0;i<n;i++){// 循环遍历数组中的每个括号 
		if(exp[i]=='('){// 判断括号是不是'(',如果是的话 
			stack[++top]='(';// 入栈 
		}
		if(exp[i]==')'){// 判断括号是不是')',如果是的话 
			if(top==-1){// 如果当前遇到的括号是")",并且栈已空,则不匹配,返回0 
				return 0;
			}else{ // 如果栈不空,则出栈。也就是划掉"()" 
				--top;
			}
		} 
	}
	/* 循环遍历括号表达式完毕后,对结果进行反馈 */ 
	if(top==-1){// 如果栈空的话,即所有括号都正确配对,返回1 
		return 1;
	}else{// 如果栈不空,则栈中存在着"(",故未能正确配对,返回0 
		return 0;
	}
} 
 
int main() {
	int result;
	
	char exp[]={'(',')','(','(',')'};
	result=match(exp,5);
	printf("是否匹配(1表示正确配对,0表示错误配对):%d",result);	

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值