惨兮兮的被刷掉2%的通过率后在经过思考和dalao的指点后终于A掉了这道题
强烈建议修改这题的样例,实在太迷惑人,各种错误算法都能过
比如说这是一份错误代码,看懂了也不要学思路,和正解不知道差到哪里去了:
惨兮兮,WA掉代码:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
using namespace std;
char a[100086];
int len,top=0,ll=0,lexn,maxx=-10000,leen;
char s[100086],bb[10086],jg[100086];
bool f=true;
int main()
{
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
cin>>a;
len=strlen(a);
for(int i=0;i<len;i++)
{
if(s[top]==‘(‘)
{
if(a[i]==‘]‘)
{memset(s,0,sizeof(s));memset(bb,0,sizeof(bb));top=0;f=false;}
else if(a[i]==‘(‘)
{
s[++top]=a[i];
bb[++ll]=a[i];
}
else if(a[i]==‘)‘)
{
bb[++ll]=a[i];
top--;
}
}
else if(s[top]==‘[‘)
{
if(a[i]==‘)‘)
{memset(s,0,sizeof(s));memset(bb,0,sizeof(bb));top=0;f=false;}
else if(a[i]==‘(‘)
{
s[++top]=a[i];
bb[++ll]=a[i];
}
else if(a[i]==‘]‘)
{
bb[++ll]=a[i];
top--;
}
}
else if(a[i]==‘(‘||a[i]==‘[‘)
{s[++top]=a[i];bb[++ll]=a[i];}
if(top==0&&f)
{
//lexn=strlen(bb);
if(maxx<ll)
{
memset(jg,0,sizeof(jg));
maxx=ll;
if(leen!=maxx)
leen=0;
for(int i=1;i<=ll;i++)
{
jg[i]=bb[i];
leen++;
}
}
ll=0;
memset(bb,0,sizeof(bb));
memset(s,0,sizeof(s));
}
if(!f)
f=true;
}
for(int i=1;i<=leen;i++)
{
if(jg[i]==‘[‘||jg[i]==‘(‘||jg[i]==‘]‘||jg[i]==‘)‘)
cout<<jg[i];
}
return 0;
}(这是WA掉的)
但即便是这个WA掉所有数据的错误代码都能过样例,所以改一下为好吧……
然后是正解思路:
读入一个char型数组,然后将此数组中的字符挨个进栈,如果碰到’]’或是’)’,就查看栈顶元素,如果是能与当前字符匹配的左括号,就进栈,bool型数组标记,否则就将栈清空,操作讲不清,代码如下:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
using namespace std;
int len,s=0,maxx=-1000,top=-1,sum=-1,num=-1,t=0;//top为栈顶下标,因为是字符串,所以为-1,sum,num同理
char a[1000086],stack[1000086];
bool f[1000086];
int d[1000010],e[1000010];//开两个数组分别记录‘(‘和‘]‘的下标
int main()
{
cin>>a;
memset(f,false,sizeof(f));
len=strlen(a);
for(int i=0;i<len;i++)
{
stack[++top]=a[i];//入栈
if(stack[top]==‘(‘)//当栈顶是(时,记录下标
d[++sum]=i;
if(stack[top]==‘[‘)//同上
e[++num]=i;
if((stack[top]==‘)‘&&stack[top-1]==‘[‘)||(stack[top]==‘]‘&&stack[top-1]==‘(‘))//当右括号与栈顶左括号不匹配时,栈清空
top=0;
else if((stack[top]==‘)‘&&stack[top-1]==‘(‘)||(stack[top]==‘]‘&&stack[top-1]==‘[‘))//当栈顶左括号与右括号匹配时
{
f[i]=1;//标记当前下标
if(stack[top]==‘]‘)//如果栈顶右括号为]?
{
f[e[num]]=1;//bool数组标记下标
num--;//存储]的数组减去一个]
}
if(stack[top]==‘)‘)//理同上
{
f[d[sum]]=1;
sum--;
}
top-=2;//因为左括号与右括号匹配,所以直接删去两个
}
}
for(int i=0;i<len;i++)
{
if(f[i])//t为能够匹配的括号式的长度
t++;
else//因为匹配括号式必须挨着,所以一旦!f[i],则说明已经记录完了一个括号式
{
if(t>maxx)//标记最大长度
{
maxx=t;
s=i;//s记录当前下标
}
t=0;
}
}
if(t>maxx)//避免式子在最后
{
maxx=t;
s=len;
}
for(int i=s-maxx;i<s;i++)//s减去maxx即为最长表达式的起始下标
cout<<a[i];
return 0;
}