简而言之,就是一个入栈计算
可以先把连续的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;
}