user-0 提问: 求问前辈们一道问题 B: 栈的操作问题

回复:
user: user-0
content: 引用 1 楼 user-1的回复:其实就是看你对栈的入栈出栈顺利的理解和把握。说白了就是比较输入的数据和栈顶的数据，根据比较结果来打印入栈出栈指令。如果输入数据和栈顶一致，就把栈顶出栈（并打印Q）；如果输入数据大于栈顶元素，就把元素一次入栈（并打印P，这里要注意没有重复入栈，所以判断一下上次入栈的最大值，如果输入数据比上次入栈的最大值小，则说明重复入栈，出错）；如果输入数据小于栈顶数据则错误打印error（因为栈顶再怎么出栈打印，打印结果也和输入数据不相符，所以是错误的）  #define Maxsize 1000 typedef struct{     int data[Maxsize];     int top; }SqStack; void InitStack(SqStack &s){     s.top=-1; } void Push(SqStack &s,int x){     if(s.top==Maxsize-1) return;     s.data[++s.top]=x; } int Pop(SqStack &s){     if(s.top==-1){         return -1;     }     return s.data[s.top--]; } int Peek(SqStack &s) { //加个查看栈顶元素的方法     if (s.top==-1) {         return -1;     }     return s.data[s.top]; }  int main(){     int n, i, j, t, m; //n是每行第一个数，i是n的计数器，j是记录上一次入栈的最大值（以后入栈只能从最大值+1开始），t是栈顶数据，m是每行的输入数据     SqStack s;     char res[2*Maxsize+1]; //res是指令结果字符串     while (scanf("%d", &n)==1 && n>0) { //获取每行第一个数n（n是0或非法输入则结束测试）         memset(res, 0, sizeof(res)); //初始化res         InitStack(s); //初始化栈         for(i=1, j=0; i<=n; i++) { //n循环             scanf("%d", &m); //获取每行的每个数据m             if (strstr(res, "error") != NULL) { //如果结果已经出错就跳过该行剩余的输入数据                 continue;             }             t = Peek(s); //获得栈顶数据             if (t==m) { //如果输入数据和栈顶一致，则打印Q，并弹出栈顶元素                 strcat(res, "Q");                 Pop(s);             } else if (t<m) { //如果输入数据大于栈顶元素（栈顶为空也包含在里面）                 if (m<j+1) { //如果m小于上次入栈的最大值+1，则出错（因为已经入过栈了，不能重复入栈）                     strcat(res, " error");                 } else { //从上次入栈的                     for(t=j+1; t<m; ++t) { //从上次入栈的最大值+1开始依次入栈，并打印P                         strcat(res, "P");                         Push(s, t);                     }                     strcat(res, "PQ"); //最后一个入栈后又马上出栈了，所以直接打印PQ                     j = m; //记录入栈过的最大值                 }             } else { //如果输入数据小于栈顶元素（那栈顶出栈打印的结果就和输入数据不相符，所以错误）                 strcat(res, " error");             }         }         printf("%s\n", res); //最后打印指令结果     }     return 0; } 前辈能解释下为什么要用栈顶元素和输入数据比较吗？ 或者说该怎么思考到这种方法思路

user: user-1
content: 其实就是看你对栈的入栈出栈顺利的理解和把握。说白了就是比较输入的数据和栈顶的数据，根据比较结果来打印入栈出栈指令。如果输入数据和栈顶一致，就把栈顶出栈（并打印Q）；如果输入数据大于栈顶元素，就把元素一次入栈（并打印P，这里要注意没有重复入栈，所以判断一下上次入栈的最大值，如果输入数据比上次入栈的最大值小，则说明重复入栈，出错）；如果输入数据小于栈顶数据则错误打印error（因为栈顶再怎么出栈打印，打印结果也和输入数据不相符，所以是错误的）  #define Maxsize 1000 typedef struct{     int data[Maxsize];     int top; }SqStack; void InitStack(SqStack &s){     s.top=-1; } void Push(SqStack &s,int x){     if(s.top==Maxsize-1) return;     s.data[++s.top]=x; } int Pop(SqStack &s){     if(s.top==-1){         return -1;     }     return s.data[s.top--]; } int Peek(SqStack &s) { //加个查看栈顶元素的方法     if (s.top==-1) {         return -1;     }     return s.data[s.top]; }  int main(){     int n, i, j, t, m; //n是每行第一个数，i是n的计数器，j是记录上一次入栈的最大值（以后入栈只能从最大值+1开始），t是栈顶数据，m是每行的输入数据     SqStack s;     char res[2*Maxsize+1]; //res是指令结果字符串     while (scanf("%d", &n)==1 && n>0) { //获取每行第一个数n（n是0或非法输入则结束测试）         memset(res, 0, sizeof(res)); //初始化res         InitStack(s); //初始化栈         for(i=1, j=0; i<=n; i++) { //n循环             scanf("%d", &m); //获取每行的每个数据m             if (strstr(res, "error") != NULL) { //如果结果已经出错就跳过该行剩余的输入数据                 continue;             }             t = Peek(s); //获得栈顶数据             if (t==m) { //如果输入数据和栈顶一致，则打印Q，并弹出栈顶元素                 strcat(res, "Q");                 Pop(s);             } else if (t<m) { //如果输入数据大于栈顶元素（栈顶为空也包含在里面）                 if (m<j+1) { //如果m小于上次入栈的最大值+1，则出错（因为已经入过栈了，不能重复入栈）                     strcat(res, " error");                 } else { //从上次入栈的                     for(t=j+1; t<m; ++t) { //从上次入栈的最大值+1开始依次入栈，并打印P                         strcat(res, "P");                         Push(s, t);                     }                     strcat(res, "PQ"); //最后一个入栈后又马上出栈了，所以直接打印PQ                     j = m; //记录入栈过的最大值                 }             } else { //如果输入数据小于栈顶元素（那栈顶出栈打印的结果就和输入数据不相符，所以错误）                 strcat(res, " error");             }         }         printf("%s\n", res); //最后打印指令结果     }     return 0; }