码迷,mamicode.com
首页 > 其他好文 > 详细

OJ1147括号匹配加强版(栈)

时间:2017-11-18 17:34:20      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:size   个数   names   int   algorithm   字符串   for   turn   一个   

惨兮兮的被刷掉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;

}

OJ1147括号匹配加强版(栈)

标签:size   个数   names   int   algorithm   字符串   for   turn   一个   

原文地址:http://www.cnblogs.com/ywjblog/p/7857285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!