third(栈与队列)!


 给你一串字符,不超过50个字符,可能包括括号、数字、字母、标点符号、空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配。

 

Input

 输入数据有多组,处理到文件结束。

 

Output

 如果匹配就输出“yes”,不匹配输出“no”

 

Example Input
sin(20+10)
{[}]
Example Output
yes
no

01 #include <bits/stdc++.h>
02  
03 using namespace std;
04  
05 int main()
06 {
07 char a[55],t[50];
08 while(gets(a))
09 {
10 int top=0,i=0;
11 int n=strlen(a);
12 for( i=0;i<n;i++)
13 {
14 if(a[i]=='('||a[i]=='['||a[i]=='{')
15 t[top++]=a[i];
16 if(a[i]==')'||a[i]==']'||a[i]=='}')
17 {
18 if(a[i]==t[top-1]+1||a[i]==t[top-1]+2)
19 top--;
20 else
21 break;
22 }
23 }
24 if(i==n&&top==0)
25 cout<<"yes"<<endl;
26 else
27 cout<<"no"<<endl;
28 }
29 return 0;
30 }
31  

堆栈是一种基本的数据结构。堆栈具有两种基本操作方式,push 和 pop。push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。

Input3335

首先输入整数t(1 <= t <= 10),代表测试的组数,以后是 t 组输入。
 对于每组测试数据,第一行输入两个正整数 m(1 <= m <= 100)、n(1 <= n <= 1000),其中m代表当前栈的最大长度,n代表本组测试下面要输入的操作数。 而后的 n 行,每行的第一个字符可能是'P’或者'O’或者'A’;如果是'P’,后面还会跟着一个整数,表示把这个数据压入堆栈;如果是'O’,表示栈顶元素出栈;如果是'A',表示询问当前栈顶的值'。

Output

 对于每组测试数据,根据其中的命令字符来处理堆栈;
(1)对所有的'P'操作,如果栈满输出'F',否则完成压栈操作;
(2)对所有的'A'操作,如果栈空,则输出'E',否则输出当时栈顶的值;
(3)对所有的'O'操作,如果栈空,则输出'E',否则输出栈顶元素的值,并让其出栈;
每个输出占据一行,每组测试数据(最后一组除外)完成后,输出一个空行。

Example Input
2
5 10
A
P 9
A
P 6
P 3
P 10
P 8
A
P 2
O
2 5
P 1
P 3
O
P 5
A
Example Output
E
9
8
F
8

3
5

01 #include <bits/stdc++.h>
02  
03 using namespace std;
04  
05 int main()
06 {
07 int a[105];
08 int t,m,n,i,top,num;
09 char s[10];
10 cin>>t;
11 while(t--)
12 {
13 top=-1;
14 memset(a,0,sizeof(a));
15 cin>>m>>n;
16 for(i=0;i<n;i++)
17 {
18 cin>>s;
19 if(s[0]=='P')
20 {
21 cin>>num;
22 if(top+1<m)
23 a[++top]=num;
24 else
25 cout<<"F"<<endl;
26 }
27 else if(s[0]=='O')
28 {
29 if(top<=-1)
30 cout<<"E"<<endl;
31 else
32 {
33 cout<<a[top]<<endl;
34 top--;
35 }
36 }
37 else if(s[0]=='A')
38 {
39 if(top<=-1)
40 cout<<"E"<<endl;
41 else
42 cout<<a[top]<<endl;
43 }
44 }
45 if(t>0)
46 cout<<endl;
47 }
48 return 0;
49 }

一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区。 

 

由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效; 

 

如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符"@",以表示当前行中的字符均无效。 

 

如果已经在行首继续输入'#'符号无效。 

Input

 输入多行字符序列,行字符总数(包含退格符和退行符)不大于250。 

Output

 按照上述说明得到的输出。 

Example Input
whli##ilr#e(s#*s)
outcha@putchar(*s=#++);
Example Output
while(*s)
putchar(*s++);
01 #include<bits/stdc++.h>
02 using namespace std;
03 int main()
04 {
05     char Stack[1000],a[1000];
06     int len,k;
07    while(gets(a))
08    {
09        int i=0;
10        k=0;
11     while(a[i]!='\0')
12     {
13         if(a[i]=='@')
14         {
15         k=0;
16         }
17        else if(a[i]=='#')
18        {
19            if(k)
20            k--;
21        }
22        else
23        {
24            Stack[k++]=a[i];
25        }
26        i++;
27     }
28     if(k)
29     {
30         for(i=0;i<k;i++)
31         {
32                 printf("%c",Stack[i]);
33         }
34         printf("\n");
35     }
36 }
37  return 0;
38 }


XX  YY 经常在自习课的时候传纸条来传递一些私密性的信息。但是他们的座位相隔比较远,传纸条要通过其他人才能到达对方。在传递过程中,难免会有一些好奇心比较强的同学偷看纸条的内容。所以他们想到了一个办法,对纸条内容进行加密。

加密规则很简单:多次在信息的任意位置随意的添加两个相同的字母。

由于使用英文交流显得比较高端,所以他们的纸条内容只有英文。

现在给你加密后的信息,请你还原出原始的内容。

Input
 

输入数据的第一行为一个整数 T(T  30),表示共有 组测试数据。

接下来 行,每行为一个字符串,字符串仅包含小写英文字母,且保证原始字符串中不包含相邻两个相同的字,字符串长度不超过200000

Output
 

每组数据输出一行字符串,表示还原后的内容。

Example Input
1
ssilofaafveuuu
Example Output
iloveu
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    char a[200005],b[200005];
    cin>>t;
    while(t--)
    {
        cin>>a;
        int n=strlen(a);
        int s=0;
        b[0]=1;
        for(int j=0; j<n; j++)
        {
            if(b[s]==a[j])
                s--;
            else
            {
                s++;
                b[s]=a[j];
            }
        }
        for(int i=1;i<=s;i++)
        cout<<b[i];
        cout<<endl;
    }
    return 0;
}

对于包含n(1<=n<=100000)个整数的序列,对于序列中的每一元素,在序列中查找其位置之后第一个大于它的值,如果找到,输出所找到的值,否则,输出-1。

Input

 输入有多组,第一行输入t(1<=t<=10),表示输入的组数;

以后是 t 组输入:每组先输入n,表示本组序列的元素个数,之后依次输入本组的n个元素。

Output

 输出有多组,每组之间输出一个空行(最后一组之后没有);

每组输出按照本序列元素的顺序,依次逐行输出当前元素及其查找结果,两者之间以-->间隔。

Example Input
2
4 12 20 15 18
5 20 15 25 30 6 
Example Output
12-->20
20-->-1
15-->18
18-->-1

20-->25
15-->25
25-->30
30-->-1
6-->-1
01 #include<bits/stdc++.h>  超时代码.数据量大使用sort函数导致时间错误。
02 using namespace std;
03     struct node
04     {
05         int x,next,pos;
06     } a[100005];
07     int cp(struct node a,struct node b)
08     {
09         return a.x<b.x;
10     }
11     int cp2(struct node a,struct node b)
12     {
13         return a.pos<b.pos;
14     }
15     int main()
16     {
17         int t,n,j;
18         cin>>t;
19         while(t--)
20         {
21             cin>>n;
22             for( j=0; j<n; j++)
23             {
24                 cin>>a[j].x;
25                 a[j].pos=j+1;
26             }
27             sort(a,a+n,cp);
28             for( j=0; j<n-1; j++)
29             {
30                 if(a[j].pos<a[j+1].pos)
31                     a[j].next=a[j+1].x;
32                 else
33                     a[j].next=-1;
34             }
35             a[n-1].next=-1;
36             sort(a,a+n,cp2);
37             for(j=0; j<n; j++)
38                 cout<<a[j].x<<"-->"<<a[j].next<<endl;
39             if(t>0)
40                 cout<<endl;
41         }
42     return 0;
43 }
44  

利用栈函数。
01 #include<iostream>
02 #include<stack>
03 using namespace std;
04 struct node
05 {
06     int num,id,next;
07 } a[100005],b;
08 int main()
09 {
10     int t,n,j,i;
11     cin>>t;
12     stack<struct node>p;
13     for(i=1;i<=t;i++)
14     {
15     if(i>1)
16     cout<<endl;
17     while(!p.empty())
18     {
19     p.pop();
20     }
21     cin>>n;
22     for(j=1;j<=n;j++)
23     {
24     cin>>a[j].num;
25     a[j].id=j;
26     a[j].next=-1;
27     if(p.empty())
28     p.push(a[j]);
29     else
30     {
31     while(!p.empty())
32     {
33     b=p.top();
34     if(b.num<a[j].num)
35     {
36     a[b.id].next=a[j].num;
37     p.pop();
38     }
39     else
40     break;
41     }
42     p.push(a[j]);
43     }
44     }
45     for(j=1;j<=n;j++)
46     printf("%d-->%d\n",a[j].num,a[j].next);
47     }
48     return 0;
49     }
50  

2135Problem Description

中午买饭的人特多,食堂真是太拥挤了,买个饭费劲,理工大的小孩还是很聪明的,直接奔政通超市,哈哈,确实,政通超市里面也卖饭,有好几种菜,做的比食堂好吃多了,价格也不比食堂贵,并且买菜就送豆浆,吸引了不少童鞋。所以有时吧,人还是很多的,排队是免不了的,悲剧的是超市只有两个收银窗口。

问题是这样的:开始有两队人在排队,现在咱们只研究第一队,现在我们给每个人一个编号,保证编号各不相同,排在前面的人买完饭就走了,有些人挑完饭就排在后面等待付款,还有一些人比较聪明,看到另一个队人比较少,直接离开这个队到另一个队去了。我要问的是队的总人数和某个位置上人的编号。



Input

首先输入一个整数m(m<10000),代表当前有m个人,第二行输入m个数,代表每个人的编号,第三行输入一个整数n(n<10000),代表队列变动和询问一共n次,以后n行,JOIN X表示编号为X(保证与以前的编号不同)的人加入;LEAVE Y表示第Y(Y小于当前队列长度)个位置 上的人离队 ;ASK Z(Z小于当前队列长度)表示询问第Z个位置上的人的编号;FINISH  D表示有D个人买完饭离开了;LENGTH表示询问队列的长度 。保证所有数据在int 范围内.

Output

对每个询问输出相应的答案,每个答案占一行。

Example Input
31 2 36JOIN 4ASK 2LEAVE 2LENGTHFINISH 2LENGTH
Example Output
231


01 #include <bits/stdc++.h>
02  
03 using namespace std;
04  
05 int main()
06 {
07     int queue[10005];
08     int n,front,rear,i,a,x,m;
09     char s[25];
10     while(cin>>m)
11     {
12         front=rear=0;
13         for(i=0; i<m; i++)
14         {
15             cin>>a;
16             queue[rear++]=a;
17         }
18         cin>>n;
19         while(n--)
20         {
21             cin>>s;
22             if(s[0]=='J')
23             {
24                 cin>>x;
25                 queue[rear++]=x;
26             }
27             else if(s[0]=='A')
28             {
29                 cin>>x;
30                 cout<<queue[front+x-1]<<endl;
31             }
32             else if(s[0]=='F')
33             {
34                 cin>>x;
35                 front+=x;
36             }
37             else if(strcmp(s,"LENGTH")==0)
38             {
39                 cout<<rear-front<<endl;
40             }
41             else
42             {
43                 cin>>x;
44                 for(i=front+x-1;i<rear-1;++i)
45                 {
46                 queue[i]=queue[i+1];
47                 }
48                 rear--;
49                 }
50                 }
51                 }
52         return 0;
53     }
1466 Problem Description

      想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首;两头都可以做出队,入队的操作。
现在给你一系列的操作,请输出最后队列的状态;
命令格式:
LIN X  X表示一个整数,命令代表左边进队操作;
RIN X  表示右边进队操作;
ROUT
LOUT   表示出队操作;

Input

第一行包含一个整数M(M<=10000),表示有M个操作;
以下M行每行包含一条命令;
命令可能不合法,对于不合法的命令,请在输出中处理;

Output

输出的第一行包含队列进行了M次操作后的状态,从左往右输出,每两个之间用空格隔开;
以下若干行处理不合法的命令(如果存在);
对于不合法的命令,请输出一行X ERROR
其中X表示是第几条命令;

Example Input
8
LIN 5
RIN 6
LIN 3
LOUT
ROUT
ROUT
ROUT
LIN 3
Example Output
3
7 ERROR

01 #include<bits/stdc++.h>
02 using namespace std;
03 int main()
04 {
05 int a[20005],left=10000,right=10000,n,x,i,flag[10005];把数组开的更大些否则会runtime
06 char s[15];
07 cin>>n;
08 for(i=1;i<=n;i++)
09 {
10 flag[i]=0;
11 cin>>s;
12 if(strcmp(s,"LIN")==0)
13 {
14 cin>>x;
15 a[--left]=x;
16 }
17 else if(strcmp(s,"RIN")==0)
18 {
19 cin>>x;
20 a[right++]=x;
21 }
22 else if(strcmp(s,"LOUT")==0)
23 {
24 if(left<right)
25 left++;
26 else
27 flag[i]=1;
28 }
29 else
30 {
31 if(left<right)
32 right--;
33 else
34 flag[i]=1;
35 }
36 }
37 cout<<a[left++];
38 while(right-left>0)
39 {
40 cout<<" "<<a[left++];
41 }
42 cout<<endl;
43 for(int k=1;k<=n;k++)
44 if(flag[k]==1)
45 cout<<k<<" ERROR"<<endl;
46 return 0;
47 }
2132Problem Description

对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之。

Input

输入一个算术表达式,以‘#’字符作为结束标志。

Output

输出该表达式转换所得到的后缀式。

Example Input
a*b+(c-d/e)*f#
Example Output
ab*cde/-f*+

首先创建栈并置空,然后依次检查中缀表达式每个字符,不同字符按不同情况处理:

若是操作数,就直接将存入字符串exp[]中。若是‘(’则将其压入栈中。

若是‘)’则依次弹栈并存入字符串exp[]中,直到遇到取出和它匹配的‘(’为止,‘

(’出栈丢弃。若是操作符,如果栈空或者该操作符的优先级大于栈顶操作符则将其放入到栈中。

如果该操作符的优先级小于等于栈顶操作符则弹出栈中的操作符存入字符串exp[]中,

直到该操作符的优先级大于栈顶操作符或栈空,然后将该操作符入栈。当读到了中缀式的末尾时,

如果栈非空则将栈中所有元素依次弹出存入字符串exp[]中,

最后见‘\0’存入exp[]中,则exp[]中存储的就是后缀表达式。


  1. #include <bits/stdc++.h>  
  2. using namespace std;  
  3. stack<int>Q;    //建立栈  
  4. void Transform(char str[])  
  5. {  
  6.     int i;  
  7.     for(i=0; str[i]!='#'; i++)  
  8.     {  
  9.         if(str[i]>='a'&&str[i]<='z')     //如果是字母的话就直接输出  
  10.         {  
  11.             cout<<str[i];  
  12.         }  
  13.         else if(str[i]=='(')    //遇到左括号,进栈  
  14.         {  
  15.             Q.push(str[i]);  
  16.         }  
  17.         else if(str[i]==')')        //遇到右括号时,如果栈顶不是左括号,则将左括号上面的数字或者符号全部输出  
  18.         {  
  19.             while(Q.top()!='(')  
  20.             {  
  21.                 printf("%c",Q.top());  
  22.                 Q.pop();  
  23.             }  
  24.             Q.pop();    //删除左括号  
  25.         }   
  26.         else if(str[i]=='+'||str[i]=='-')  
  27.         {  
  28.             while(!Q.empty()&&Q.top()!='(')    //运算级较低,满足条件时输出  
  29.             {  
  30.                 printf("%c",Q.top());  
  31.                 Q.pop();  
  32.             }  
  33.             Q.push(str[i]);        //如果不是以上符号的话,就進入栈中存储        
  34.         }  
  35.         else if(str[i]=='*'||str[i]=='/')  
  36.         {  
  37.             while(!Q.empty()&&Q.top()!='('&&(Q.top()=='*'||Q.top()=='/'))  
  38.             {  
  39.                 printf("%c",Q.top());  
  40.                 Q.pop();  
  41.             }  
  42.             Q.push(str[i]);  
  43.         }  
  44.     }  
  45.     while(!Q.empty())  //输出所有的元素  
  46.     {  
  47.         printf("%c",Q.top());  
  48.         Q.pop();  
  49.     }  
  50. }  
  51. int main()  
  52. {  
  53.     char str1[110];  
  54.     scanf("%s",str1);  
  55.     Transform(str1);  
  56.     cout<<endl;  
  57. return 0;  
  58. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值