数据结构第二章-线性结构4 Pop Sequence

Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.

Output Specification:

For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not.


想法:

sq1用于存储目前序列,其栈顶用于指示想要输出的元素(即为sq1->data[sq1->top])

sq2用于模拟出入栈的行为。


(1) sq1->data[sq1->top] 等于 sq2中栈顶的元素 sq2->data[sq2->top]。那就直接pop(sq1)和pop(sq2)。

(2) sq1->data[sq1->top] 大于 sq2中栈顶的元素sq2->data[sq2->top],则一直压入直到 sq2->data[sq2->top] == sq1->data[sq1->top] 。留意每push一次就要让push_idx增一,并且判断sq2有没有溢出,如果溢出就break。

(3) sq1->data[sq1->top] 小于 sq2中栈顶元素sq2->data[sq2->top],此时就凉了。break。


所以再综合看(2)和(3),发现小于的时候是无能为力的,大于的时候就push,

所以可以将(2)和(3)综合成一类来写:

  只要 sq1->data[sq1->top] 等于 sq2中栈顶的元素 sq2->data[sq2->top], 就push,直到溢出。

 因此可以简化代码。


判断yes的标准:两个sequence都清空了。


代码实现:

(1) 正确的是这样:

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 1000

typedef struct {

    int data[MaxSize];

    int top;

}dataStack;

typedef dataStack *stackPrt;

void Push (stackPrt stackTop, int datain){

    if (stackTop->top > (MaxSize-1))

        printf("stack full");

    else{

        stackTop->data[++(stackTop->top)] = datain;   // not necessarily add one, since the data might take 8 bits

    }

};

int Pop (stackPrt stackTop){

    if (stackTop->top == -1){

        printf("stack empty");

        return 1;

    }else{

        return stackTop->data[(stackTop->top)--];

    }

};

int main(){

    int M,N,K,push_idx;

    dataStack sq01,sq02;

    stackPrt sq1=&sq01, sq2=&sq02;  //sq1 store the sequence and sq2 simulate the push and pop

//    printf("enter M N K: \n");

    scanf("%d %d %d", &M,&N,&K);

    while(K--){

        fflush(stdin);

        sq1->top = -1; sq2->top = -1;

//        printf("\nenter list:\n");

        for (int j=N-1; j>-1; j--) scanf("%d",&(sq1->data[j]));   //reverse store

        sq1->top = N-1;                                         //adjust the stack pointer

        push_idx=1;

        while (push_idx <= N+1){

            if ((sq1->data[sq1->top]) == (sq2->data[sq2->top])&&(sq2->top != -1)){

                Pop(sq1); Pop(sq2);  // in case of two empty sequences

            }else if ((sq2->top < M-1)&&(push_idx<N+1)){

                Push(sq2, push_idx);

                push_idx++;

            }else break;

        }

        if (sq2->top == -1 && sq1->top == -1)

            printf("YES\n");

        else

            printf("NO\n");

    }

    return 0;

}

(2) 错误示范_留作纪念 ( (´-ω-`) 

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 1000
typedef struct {
    int data[MaxSize];
    int top;
}dataStack;
typedef dataStack *stackPrt;

void Push (stackPrt stackTop, int datain){
    if (stackTop->top > (MaxSize-1))
        printf("stack full");
    else{
        stackTop->data[++(stackTop->top)] = datain;   // not necessarily add one, since the data might take 8 bits
    }
};

int Pop (stackPrt stackTop){
    if (stackTop->top == -1){
        printf("stack empty");
        return 50000;
    }else{
        return stackTop->data[(stackTop->top)--];
    }
};
    
int main(){
    int M,N,K,push_idx;
    int flag;           //identifier
    dataStack sq01,sq02;
    stackPrt sq1, sq2;  //sq1 store the sequence and sq2 simulate the push and pop
    sq1 = &sq01; sq2 = &sq02;
    sq1->top = -1; sq2->top = -1;
//    printf("enter M N K: \n");
    scanf("%d %d %d", &M,&N,&K);
    for (int i=0; i<K; i++){
        fflush(stdin);
        flag = 1;
//        printf("\nenter list:\n");
        for (int j=N-1; j>-1; j--) scanf("%d",&sq1->data[j]);   //reverse store
        sq1->top = N-1;                                         //adjust the stack pointer
        push_idx=1;
        while (flag && (sq2->top + sq1->top)!=-2){              //all stacks are clean

            if (sq2->top != -1 && flag){
//                printf("%d %d\n",sq2->data[sq2->top],sq1->data[sq1->top]);
                if (sq2->data[sq2->top] >= sq1->data[sq1->top]){
                    if (Pop(sq2) != sq1->data[sq1->top]) flag = 0;
                    else Pop(sq1);
                }else if (sq2->data[sq2->top] < sq1->data[sq1->top]){
                    while (flag && push_idx <= (sq1->data[sq1->top])){
                        Push(sq2, push_idx);
                        push_idx++;
                        if (sq2->top > M && push_idx > N+1) flag = 0;
                    }
                }
            }else if (flag && sq2->top == -1){                    //sq2 is empty
//                printf("%d %d\n",sq2->data[sq2->top],sq1->data[sq1->top]);
                Push(sq2, push_idx);
                push_idx++;
                if (push_idx > N+1) flag = 0;
            }
        }
        if (flag) printf("YES\n");
        else printf("No\n");
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值