每日总结-----12月15日

今天只完成了一道题,学习了出栈序列的合法性,也因为这个卡了一个晚上。

写的题是第二周任务(栈+队列+搜索模板)中的c题:

您将获得一个由括号( )[ ]组成的字符串。这种类型的字符串被认为是正确的:

  • 如果是空字符串
  • 如果AB是正确的,AB是正确的,
  • 如果A是正确的,(A) 和 [A] 是正确的。

编写一个程序,该程序采用此类型的字符串序列并检查其正确性。您的程序可以假定最大字符串长度为128

思路:

将左括号输入,将右括号用于消除。按照栈的定义,左括号可以与右括号对应。

#include<iostream>	
#include<string.h>	
#include<stack>		
using namespace std;
const  int max_n = 1e5 + 10;	

char Q[max_n];					
int top = 0;						

void push (char x){//入栈
	Q[top ++] = x;
}

char pop(){//出栈
	return Q[--top];								
}
void pop1(){//退顶
	--top;								
}

int main()
{
	int n ;
	scanf("%d" , &n);
	
	char s[130];
	int a[1001];
	char o;
	for( int m = 0 ; m < 1001 ; m ++){
		a[m] = 0;
	}
	
	int m ;
	stack<char>v;
	for( m = 0 ; m <= n ; m ++){
		
		gets(s);
		
		int u = strlen(s);
		if(u == 0){a[m] = 1; continue;}//根据题意若无输入直接Yes
		int t ;
		for( t = 0 ; t < u ; t ++){
			if( s[t] == '(' || s[t] == '[' ){//如果输入是左括号将括号存入
				push( s[t] );
			}
			else if(top == 0){break;}
			else if(top!=0){
				if(s[t] == ')') o = '(';//若输入为右括号,将右括号变为左括号,用于消去栈中的括号
				if(s[t] == ']') o = '[';
				if(pop() == o){continue;}
				else break;
			}
		}
		if( t == u && top == 0)a[m] = 1;
		else a[m] = 0;
		while(top!=0){//将栈顶退回
			pop1();
		}
	}
	
	for( m = 1 ; m <= n ; m ++){
		if(a[m] == 1)printf("Yes\n");
		else printf("No\n");
	}
	
	return 0;
}

出栈的合法性:

因为栈的限制“后进先出”,所以栈的输出有限制,但是可以通过入栈出栈的顺序改变输出结果。不过还是有限制。

例题

现在有n个元素分别是1,2,3,...,n,我们想知道通过一个栈,在n次push/pop后,出栈序列可能是什么样的。例如n是5,那么入栈次序就是1,2,3,4,5,如果我们希望出栈次序同样是1,2,3,4,5,那只要每push一个数,就立即pop一个数。如果我们希望出栈次序是3,2,4,5,1,那么我们先让1,2,3入栈,然后pop出来3和2,接着4入栈后马上pop,再就是5入栈后马上pop,最后再把栈里的1pop出。再例如,如果我们希望出栈次序是5,4,1,2,3,这是办不到的,如果要让5最先出栈,那么出栈次序只可能是5,4,3,2,1

思路:

用另一个栈来存数,将待测序列依次与i(1~N)比对,若相同继续对比,若不同则将i存入新栈,直至序列有数与相等。然后继续将序列与i对比若不同则与新栈出栈的数对比,若相同则继续,如不同则合法。

题解还在写,因为没有看清题意,正在加班赶。后续补上。

了解了一下c++里面的stack,用这个可以不用自己写入栈,出栈了。很方便,但是需要了解栈的底层代码,初学时还是需要自己写,多了解一些。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kukudeYSB

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值