02-线性结构4 Pop Sequence

**

## 堆栈模拟

**
思路:做堆栈去模拟目标序列(即带检查序列)的产生。
1.建立两个堆栈,一个为输入stack,提供输入值;
一个为检查stack,负责检验目标值(即读入值);
2.判断第一个是否大于stack的容量,是则继续,
否则不断push直到目标值为止,并抛出目标值;
3.开始进入循环,当两个stack都空时为止,
循环中对每一个读进来的目标值进行一些分类;
4.释放空间,返回1;
#include <stdio.h>
#include <stdlib.h>

typedef struct stack* Stack;
struct stack{
 int MaxSize;
 int top;
 int* STACK;
};
Stack CreateStack(int N);
int isFull(Stack s);
int isEmpty(Stack s);
int Push(Stack s,int digit);
int Pop(Stack s);
int Check(int sMax, int iLength);

int main(int argc, char *argv[]) {
 int M,N,K;
 scanf("%d%d%d",&M,&N,&K);
 int i;
 int a[K];
 for(i=0;i<K;i++){
  if(Check(M,N)) a[i]=1;
  else a[i]=0; 
 }
 for(i=0;i<K;i++){
  if(a[i]) printf("YES\n");
  else printf("NO\n");
 }
 return 0;
}

/*Skip是为了跳过后面的函数因return 0而没读到的数字,
也就是为了读完一行输入的数字*/
void Skip(int n){
 int a;
 while(n){
  scanf("%d",&a);
  n--;
 }
}

int Check(int sMax, int iLength){
//建立输入stack和检查stack
 Stack sInput=CreateStack(iLength);
 Stack sCheck=CreateStack(sMax);
 int i;
 for(i=iLength;i>=1;i--) Push(sInput,i);
 int n,cnt=0;//cnt为计算读入了多少个值,为后面Skip函数做准备
 scanf("%d",&n);
 cnt++;
 if(n>sCheck->MaxSize+1){
  Skip(iLength-cnt);
  return 0;
 }
 for(i=1;i<=n;i++) Push(sCheck,Pop(sInput));
 Pop(sCheck);
 while(!(sInput->top==-1 && sCheck->top==-1)){
  scanf("%d",&n);
  cnt++;
  int flag=0;//为检验后面程序中stack是否被压爆
  
  /*当目标值大于检查stack的top时,
  检查stack可以不断地从输入堆中拿值过来,
  当拿到目标值时弹出目标值与目标抵消;
  当目标值等于检查stack的top时,
  检查stack直接抛出与目标值相抵即可;
  目标值小于栈顶值时,没办法绕开上面的值去取下面的值,
  因此必须先抛出些与目标无关的值,这样就不符合目标值了。  
  因此有了以下的判断:*/
  
  if(sCheck->top!=-1 && n<sCheck->STACK[sCheck->top]){
   Skip(iLength-cnt);
   return 0;
  }
  if(sCheck->top!=-1 && n==sCheck->STACK[sCheck->top]) 		     
  Pop(sCheck);
  else{
   i=Pop(sInput);
   while(i!=n) {
    if(!Push(sCheck,i)){
     flag=1;
     break; 
    }
    i=Pop(sInput);
   }
   if(!Push(sCheck,i)) flag=1;
   else Pop(sCheck);
   if(flag) {
    Skip(iLength-cnt);
    return 0;
   }
  }
 } 
 
 free(sCheck);sCheck=NULL;
 free(sInput);sInput=NULL;
 
 return 1;
}

Stack CreateStack(int N){
 Stack s=(Stack)malloc(sizeof(struct stack));
 s->STACK=(int*)malloc(N*sizeof(int));
 s->top=-1;
 s->MaxSize=N-1;
 return s;
}

int isFull(Stack s){
 return (s->top==s->MaxSize);
}

int isEmpty(Stack s){
 return (s->top==-1);
}

int Push(Stack s,int digit){
 if(isFull(s)) return 0;
 s->STACK[++s->top]=digit;
 return 1;
}

int Pop(Stack s){
 if(isEmpty(s)) return 0;
 return s->STACK[s->top--];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值