c语言中判断圆括号是否配对的一个思路<针对新手村居民>

我们先来看一道题:

任意给定一个字符串,字符串中包含除了空白符,换行符之外的任意字符。你的任务是检测字符串中的圆括号是否配对,比如说"((a+b)*(c+d))"中的圆括符就是配对的,而"((a+b)))*(c+d)"就不配对。

初看此题很多人会理所当然地认为只要括号数量相同就能配对,然而真的是这样吗?我们看一下例子((a+b)+((c+d)*(1+c))),这个字符串的括号明显是配对的,我们随意调换括号之间的顺序,显然括号总数没有变,然而这个——))a+b(+))c+d(*(1+c(((显然就离谱了。

接下来开始分析这个题目:

不配对的一共有一下几种情况:

1,括号数量不匹配。

2,存在一个括号找不到相对应的括号。

这里相对应的意思是指逻辑上的对应,不是简单的数量上的对应,如果能达到2满足的一一对应的要求那么他们数量上的要求也就满足了。接下来为了简化问题,我们把一个字符串中的所有圆括号都拿出来单独作为一个数组来研究。为了简单起见,我定义了一个整形数组,并且用1表示'(',2表示')'。举个例子,对于字符串"(((a+b)+(c+d)*(d+f))+(5-f))"经过转化后就以{1,1,1,2,1,2,1,2,2,1,2,2}的形式储存在了一个整形数组中。我们发现相邻的1,2代表他们是原来字符串中最内层的括号,可以直接“消掉”,间隔为两个括号的1,2代表他们是原来字符串中倒数第二层的括号,接着“消掉”……重复这个过程,倘若我们把“消掉”定义成0。那我们就以{1,1,1,2,1,2,1,2,2,1,2,2}为例,第一层消掉间隔为0的1,2后变为{110000002002},第二层消掉间隔为2的后不变依然为{110000002002},第三层依然不变,第四次消去间隔为6处理后变为{100000000002}……最后将在第六次消去后变为{0,0,0,0,0,0,0,0,0,0,0,0}。当全部为0时表示一对一对消去成功,自然就说是括号配对了。

下面是仓促写就的代码,新手村之间可以互相交流,也欢迎大神前来改进:

#include<stdio.h>
int main()
{
	char a[100];
	gets(a);//输入字符串数组
	int i = 0, b[100] = { 0 },j=0;
	while (a[i] != '\0')//把括号类型转变为int类型,如((a+b)*((c+d)+5))将会被转化为11211222储存在b中
	{
		if (a[i] == '(')
		{
			b[j++] = 1;
		}
		else if(a[i]==')')
		{
			b[j++] = 2;
		}
		i++;
	}
	for (int m = 1; m <=50; m += 2)//对括号由小到大消去,从相邻的括号开始消,如第一次消去后b[]变为10010022
	{
		for (int k = 0; k < j-m; k++)
		{
			if (b[k] == 1 && b[k + m] == 2)
			{
				b[k] = 0;
				b[k + m] = 0;
			}
		}
		int sum = 0;
		for (int n = 0; n < j; n++)
		{
			sum += b[n];
		}
		if (sum == 0)
		{
			printf("yes配对");
			return 0;
		}
	}
	printf("no未配对");
}

各位读者也可自行思考如何将这个思路应用于多种括号的配对判断,也可以思考如何加入对括号逻辑的更进一步判断,比如说"(((a+b)))"中外围两层括号是毫无必要的(可能下一期就写这个)。这里用的都是基础语句,主要提供初学者交流学习之用。

你好,我可以回答您的问题。设计c语言算法判断一个算术表达式的圆括号是否正确配对的方法如下: 1. 定义一个栈,用来存储左括号; 2. 遍历算术表达式的每个字符,如果是左括号 '(',则将其入栈; 3. 如果是右括号 ')',则将栈最后一个左括号出栈; 4. 如果栈空或最后一个括号不是配对的左括号,则算法结束,返回“不正确”; 5. 如果遍历完所有字符后,栈非空,则返回“不正确”,否则返回“正确”。 代码实现如下: ``` #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAXSIZE 100 typedef char ElemType; typedef struct { ElemType data[MAXSIZE]; int top; } Stack; void InitStack(Stack *S) { S->top = -1; } bool Push(Stack *S, ElemType x) { if (S->top == MAXSIZE - 1) { return false; } S->data[++(S->top)] = x; return true; } bool Pop(Stack *S, ElemType *x) { if (S->top == -1) { return false; } *x = S->data[(S->top)--]; return true; } bool GetTop(Stack *S, ElemType *x) { if (S->top == -1) { return false; } *x = S->data[S->top]; return true; } bool IsPair(ElemType left, ElemType right) { if (left == '(' && right == ')') { return true; } return false; } bool IsCorrectExpr(char *str) { Stack S; InitStack(&S); int i = 0; while (str[i] != '\0') { if (str[i] == '(') { Push(&S, '('); } else if (str[i] == ')') { ElemType left; if (Pop(&S, &left) && IsPair(left, str[i])) { // do nothing } else { return false; } } else { // ignore other characters } i++; } return S.top == -1; } int main() { char str[MAXSIZE]; printf("请输入一个算术表达式:"); scanf("%s", str); if (IsCorrectExpr(str)) { printf("括号匹配正确\n"); } else { printf("括号匹配错误\n"); } return 0; } ``` 希望能够帮助您解决问题。如果有任何疑问,请随时提出。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值