堆栈基本操作

描述

依次读入序列元素1,2,...,n进栈,每进一个元素,机器可要求下一个元素进栈或弹栈,如此进行。给定一个输入序列,判断栈空时弹出的元素构成的序列是否可能等于给定的序列,如果是则输出栈的操作过程,否则输出“NO”。

输入

输入分两行
第一行为n的值(即序列元素个数)
第二行为给定的输入序列(序列元素均为整型)

输出

如果输入序列能够由题目规定的操作得到,则输出对栈的操作过程
否则直接输出“NO”

样例输入

7
4 5 3 6 2 7 1

样例输出

PUSH 1
PUSH 2
PUSH 3
PUSH 4
POP 4
PUSH 5
POP 5
POP 3
PUSH 6
POP 6
POP 2
PUSH 7
POP 7
POP 1

提示

给定序列中有可能有不在1...n之间的数字

思路

不要想的太复杂,不需要用网上那些关于出栈顺序的结论,用了也不会推也记不住,就模拟一个栈就行了

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXL=100010;
vector<int> v;
int n;
int visited[MAXL];
bool isLegal(){
    stack<int> sk;
    int idx=1;
    int k=0;
    while(idx<=n){
        sk.push(idx++);
        while(!sk.empty()&&sk.top()==v[k]){
            sk.pop();
            k++;
        }
        
    }
    return sk.empty()&&k==n;
}
int main(){

    //数据的输入和非法输入判断
    cin>>n;
    for(int i=0;i<n;i++){
        int tmp;
        cin>>tmp;
        if(visited[tmp]||tmp<=0||tmp>n){
            cout<<"NO"<<endl;
            system("pause");
            return 0;
        }
        v.push_back(tmp);
        visited[tmp]=1;
    }

    //判断是否合法
    if(!isLegal()){
        cout<<"NO"<<endl;
        system("pause");
        return 0;
    }

    //模拟栈
    stack<int> sk;
    int i=0;//i是出栈的指针
    int j=1;//j是入栈的指针
    while(i<n){//最后一个操作是出栈
        if(!sk.empty()&&sk.top()==v[i]){
            cout<<"POP "<<v[i]<<endl;
            sk.pop();
            i++;
        }
        else{
            cout<<"PUSH "<<j<<endl;
            sk.push(j);
            j++;
        }
    }
    system("pause");
}

回文是指正反顺序都相同的词语。比如“level”、“deified”、“civic”等都是回文。判断一个字符序列是否为回文,可以使用或队列的基本运算。 的基本运算包括进栈和出,可以将字符序列从左到右依次进栈,然后再依次,得到的序列就是原序列的倒序。而队列的基本运算包括入队和出队,可以将字符序列从左到右依次入队,然后从左右两端各出队一个字符进行比较,如果相等则继续比较,直到队列为空或出现不相等的字符。 根据上述思路,设计一个算法如下: 1. 初始化一个S和一个队列Q; 2. 读入字符序列,将每个字符依次进栈和入队; 3. 从队列的左端和右端各出队一个字符进行比较,如果相等则继续比较,直到队列为空或出现不相等的字符; 4. 如果队列为空,则说明字符序列是回文,否则不是回文。 下面是该算法的C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_SIZE 100 // 定义结构体 struct Stack { char data[MAX_SIZE]; int top; }; // 定义队列结构体 struct Queue { char data[MAX_SIZE]; int front, rear; }; // 初始化 void initStack(struct Stack *S) { S->top = -1; } // 判断是否为空 bool isEmptyStack(struct Stack S) { return S.top == -1; } // 判断是否已满 bool isFullStack(struct Stack S) { return S.top == MAX_SIZE - 1; } // 进栈 void push(struct Stack *S, char c) { if (isFullStack(*S)) { printf("Stack overflow!\n"); exit(1); } S->data[++S->top] = c; } // 出 char pop(struct Stack *S) { if (isEmptyStack(*S)) { printf("Stack underflow!\n"); exit(1); } return S->data[S->top--]; } // 初始化队列 void initQueue(struct Queue *Q) { Q->front = Q->rear = -1; } // 判断队列是否为空 bool isEmptyQueue(struct Queue Q) { return Q.front == -1; } // 判断队列是否已满 bool isFullQueue(struct Queue Q) { return Q.front == (Q.rear + 1) % MAX_SIZE; } // 入队 void enqueue(struct Queue *Q, char c) { if (isFullQueue(*Q)) { printf("Queue overflow!\n"); exit(1); } if (isEmptyQueue(*Q)) { Q->front = Q->rear = 0; } else { Q->rear = (Q->rear + 1) % MAX_SIZE; } Q->data[Q->rear] = c; } // 出队 char dequeue(struct Queue *Q) { if (isEmptyQueue(*Q)) { printf("Queue underflow!\n"); exit(1); } char c = Q->data[Q->front]; if (Q->front == Q->rear) { Q->front = Q->rear = -1; } else { Q->front = (Q->front + 1) % MAX_SIZE; } return c; } int main() { struct Stack S; struct Queue Q; char c; bool isPalindrome = true; // 是否为回文 initStack(&S); initQueue(&Q); printf("Please input a character sequence (end with \\n): "); while ((c = getchar()) != '\n') { push(&S, c); enqueue(&Q, c); } while (!isEmptyQueue(Q)) { if (dequeue(&Q) != pop(&S)) { isPalindrome = false; break; } } if (isPalindrome) { printf("The character sequence is palindrome.\n"); } else { printf("The character sequence is not palindrome.\n"); } return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值