[刷题之旅no16]P3719 [AHOI2017初中组]rexp

本文探讨了一种使用栈处理连续字符并进行计算的方法,同时对比了递归解决类似问题的思路。在处理括号、运算符和数字时,栈的运用能有效地管理计算顺序。然而,代码中存在一些错误,如数组名混淆、死循环等问题,通过修正这些错误,实现了正确计算。递归方法则以更简洁的方式处理了优先级区域,通过递归处理表达式片段并返回最大值。文章强调了递归与栈在解决这类问题时的相似性,并提供了两种不同的实现代码。
摘要由CSDN通过智能技术生成

简而言之,就是一个入栈计算
可以先把连续的a转化为数字,然后进行计算即可
1.空栈
2.当前元素
若是数字,直接入,但是需要判断当前栈顶是否ok
若是左括号
若是右括号
开始出栈进行计算。
栈顶元素大于0
栈顶元素等于0
栈顶元素等于-1
说明当前计算完毕了。
直接stack[top]=sum即可
当前发现了一个错误
在数组转化的时候,连续的a没有合并成一个数字
原来是数组名字写错了:注意以后起名字不要太相似了,而且一定要有较高的标识度
一直没有结果出现,说明出现了死循环!好吧,有一个循环没有break。。。看来不应该疲劳编程!
看来逻辑上还是存在一些问题。
结尾的stack没有得出我想要的结果哎
因为您的stack的top是从1开始,结果是对的
大佬的思想:
又是递归,感觉这么看,递归和栈可以相互转化呀!
递归思想
设置四个判断,分别处理
一直读取
如果是a,j++
如果是左括号,相当于框进了一个区域内,所以直接递归,把表达式代入一个全新的地盘
如果是|,那么返回当前累加的j和再次递归p(0)也就是之后那一部分的最大值
如果是右括号,说明当前取余结束,直接break即可
最后return j;也就是把函数值返回,聪明,太聪明了
跟我上午做的表达式求值有异曲同工之妙,妙不可言!
看来以后这种有优先级问题的式子尤其是有括号的这种,都可以用递归来解决,因为一旦出现优先级区域,就可以用递归处理这一段表达式,然后返回值回到上级函数进行计算就好了!
记住,比较两个数的较大值,不可以把递归式给加进去,不然比较不出来
放代码:
我的栈形式

#include<stdio.h>
char st[100005];
int top=0,stack[100005]={0},str[100005]={0},sum=0;
int main()
{
	//输入 
	scanf("%s",st); 
	//直接处理比较好
	int j=0;
	//转化 
	for(int i=0;;i++)
	{
		if(st[i]=='(')//左括号 
		{
			str[j]=-1;
			j++;
		}
		else if(st[i]==')')
		{
			str[j]=-2;
			j++;
		}
		else if(st[i]=='|')
		{
			str[j]=0;
			j++;
		}
		else if(st[i]=='a')
		{
			while(1)
			{
				str[j]++;
				if(st[i+1]!='a')
				{
					j++;//说明即将结束了 
					break;
				}
				i++; 
			}
		}
		else if(st[i]=='\0')
		{
			j--; 
			break;
			//此时j代表着数组str的长度。 
		}
	}
//	//测试 
//	for(int i=0;i<=j;i++)//有问题 
//	{
//		printf("%d",str[i]);
//	}
//	printf("\n");
	//遍历读取//左括号当作-1,或者|当作0来看待、
	//处理得结果 
	for(int i=0;i<=j;i++)//现在直接遍历str int数组进行判断就可以了! 
	{
		//如果栈是空的直接入栈 ,怎么入!两种情况1种是a,一种是(以后都不会再空栈,最少也有一个
		if(i==0)//只能是最开始的时候空栈
		{
			top++;
			stack[top]=str[i];
			continue; 
		}
		if(str[i]==-1||str[i]==0)//说明遇到左括号或者较大值了,直接入
		{
			top++;
			stack[top]=str[i];
		}
		else if(str[i]>0)//说明有数字 
		{
			sum=str[i];//初始化sum 
			while(1)//循环一 
			{
				//输出sum寻找问题 
//				printf("%d\n",sum); 
//				printf("循环1\n");//看来是循环一出现了问题 
				if(stack[top]<=0)//说明你可以直接进栈了,不用合并
				{
					top++;
					stack[top]=sum;//最终的数字 
					break;
				}
				else//可以合并 
				{
					sum=sum+stack[top];
					top--;
				}
			}
		}
		else if(str[i]==-2)//遇到了右括号 
		{
			//开始出栈进行计算了。 直到遇到左括号才罢休的那种
			sum=0;
			while(1)
			{
				//输出sum寻找问题 
//				printf("%d\n",sum); 
//				printf("循环2\n");
				if(stack[top]==-1)//遇到左括号
				{
					top--;//不理他了,让他出栈,看下面 
					//还要保持最简化,合并啊
					while(1)//让当前的sum和栈顶元素进行比较 
					{
						//输出sum寻找问题 
//						printf("%d\n",sum); 
//						printf("循环3\n");
						if(stack[top]<=0)//说明你可以直接进栈了,不用合并
						{
							top++;
							stack[top]=sum;//最终的数字 
							break;
						} 
						else//可以合并 
						{
							sum=sum+stack[top];
							top--;
						}
					}
					break;
				}
				else if(stack[top]>0)//先存着 
				{
					sum=stack[top];
					top--;
				}
				else if(stack[top]==0)//遇到比较符号了
				{
					top--;//要取到我需要的数字
					sum=sum>stack[top]?sum:stack[top]; 
					//取到最大值之后入栈
					stack[top]=sum;
				}
			}	 
		}
	}
	//开始把栈中的最大值求出来就行了
	sum=stack[top];
	//测试是否可以到达这一步. 
//	printf("stack遍历:\n");
//	for(int i=1;i<=top;i++)
//	{
//		printf("%d\n",stack[i]);
//	}
//	//测试 到不了 
	while(1)
	{
		top=top-2;
		if(top==-1)
		{
			printf("%d",sum);
			break;
		}
		sum=sum>stack[top]?sum:stack[top];
		stack[top]=sum;
	}
	return 0;
 }

大佬的递归:

#include<stdio.h>
int dg(int j); 
int max(int a,int b);
int main()
{
	printf("%d",dg(0));
	return 0;
}

int dg(int j)
{
	char c;
	while((scanf("%c",&c))!=EOF)
	{
		if(c=='a') j++;
		if(c=='(') j=j+dg(0);
		if(c=='|') return max(j,dg(0));//这一步比较难以理解 懂了 
		if(c==')') return j; 	
	}
	return j;
}
int max(int a,int b)
{
	return a>b?a:b;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值