数据结构__之栈,队列

数据结构___之一的栈可以用一个特别(相对)形象的例子:一桶薯片(为什么是薯片??),你往里面倒薯片,当你取薯片的时候,你总是先取最顶部的薯片,然后一片片地向下取,先倒进去的薯片后取出,后倒进去的先取出,即以一种先进后出(后进先出)的形式取薯片。这个例子已经很形象了有道特别明显要用栈来写的题目,called“火车进站”(其实是火车进栈。。。)。题目大致就是这么个意思:有n辆火车,以顺序的方式(1,2,3,4。。。。)进站,输入一种出站方式,判断是否合法。。。。(很明显要用栈了,我就直接给代码了...)

 具体代码:

#include<bits/stdc++.h>
using namespace std;
int n,top=0,a[10000]={1},b[10000]={},c[10000]={},i=0,go=1;//b数组模拟的是一个栈,top表示栈顶;
int main()
{
 cin>>n;
 while(a[i]!=0)
 {
  cin>>a[++i];
  if(i==n)//当输入的个数足够时
  {
   i=0;
   for(int j=1;j<=n;j++)
   {
    b[++top]=j;//每辆火车依次入站
    while(b[top]==a[go])//当发现某辆火车正好可以到达出栈顺序中他所应该在的位置时
    {
     if(top==0) break;
     top--;//火车出栈
     go++;
    }
   }
   if(top==0) cout<<"Yes"<<endl;//如果车站为空(即满足了输入的出栈顺序),输出“Yse”
   else cout<<"No"<<endl;//如果车站不为空(既没有满足所输入的出栈顺序),输出“No”
   top=0;
   go=1;
  }
 }
 return 0;
}

以上是代码。

对于栈,还有类似的,但没那么明显(明明很明显)要使用栈的,比如说括号匹配:

劣质的题目描述:输入一个字符串,检测里面的括号(只包括小括号“()”)是否匹配。

当看到这题面时,我很智障地想了想,打算统计左右括号的个数,查看是否一样(代码太丑不敢发),但是,过后我又很机智(迟钝)地想到,万一出现“(()))”(语文太差不会描述)之类的情况也不合法。于是我又突然想到了一种奇妙的算法:栈!!!

于是我二话不说又写了个代码:

#include<bits/stdc++.h>
using namespace std;
string a;
int x=0;//我只是懒得开数组。。。
int main()
{
 cin>>a;
 if(a.size()<=0)//有个很坑的数据就是什么都没有。。。
 {
  cout<<"NO"<<endl;
  return 0;
 }
 for(int i=0;i<a.size();i++)
 {
  if(a[i]=='(')
  {
   x++;//省略了入站,栈顶++
  }
  if(a[i]==')')
  {
   x--;//省略了出栈,栈顶--
  }
  if(x<0)//出现了上面提到的情况
  {
   cout<<"NO"<<endl;
   return 0;//直接判定不合法,结束
  }
 }
 if(x==0)
 {
  cout<<"YES"<<endl;//合法匹配
 }
 else
 {
  cout<<"NO"<<endl;//不合法匹配
 }
 return 0;
}

咳咳(有了注释我就不多讲了)。(代码风格又臭又长不要在意。。。)

好的接下来就是队列,于是我又要不厌其烦的举一个栗子:你,,在食堂打饭,当然了,你肯定需要排队这个时候就可以把整个队伍看成一个队列,先来的先打饭,后来的后打饭,即是一种先进先出(后进后出)的顺序。这个很形象,我就不举(脑残的)例子了,直接看例题:

题面:机器翻译文章,但是!!机器很不咋滴,既能记住m个词语(还要翻字典。。。),当这时看到它不认识的词语,他就要遗忘最开始记住的词语去记一个新的词语。(其实很明显用队列(其实是我懒。。。),所以直接给代码和注释)

正宗(盗版)代码如下:

#include<bits/stdc++.h>
using namespace std;
int m,n,a,b[1001]={},hd=0,tl=0,ans=0;
int main()
{
 cin>>m>>n;
 for(int i=1;i<=n;i++)
 {
  cin>>a;
  for(int j=hd;j<=tl;j++)
  {
   if(a==b[j])//如果现在仍然记得这个词语
   {
       break;
   }
   if(a!=b[j]&&j==tl)//如果不记得
   {
    ans++;
    if(tl-hd+1<m)//如果队列长度(即记住词语的总个数)加一个不超过m个
    {
     b[++tl]=a;
    }
    else//否则(即再多记词语会超过m个)
    {
     hd++;
     tl++;
     b[tl]=a;//以往最开始记的词语(即队列队首)
    }
   }
  }
 }
 cout<<ans<<endl;
 return 0;
}

望各位大佬不要介意本蒟蒻又臭又长又简略的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值