|
|
- #include <stdio.h>
- #include <stdlib.h>
- /* 辅助函数:打印栈内容,形如 [1, 3, 4](自底向顶) */
- static void print_stack(const int *st, int top) {
- putchar('[');
- for (int i = 0; i <= top; ++i) {
- if (i) printf(", ");
- printf("%d", st[i]);
- }
- putchar(']');
- }
- /* 核心模拟:当 print_ops=1 时打印过程,=0 时仅判断合法性 */
- static int simulate_and_maybe_print(const int *b, int n, int print_ops) {
- int *st = (int *)malloc(sizeof(int) * (n > 0 ? n : 1));
- if (!st) {
- fprintf(stderr, "内存分配失败\n");
- exit(1);
- }
- int top = -1; // 栈顶指针,-1 表示空
- int nextPush = 1; // 下一个要入栈的数(1..n)
- for (int i = 0; i < n; ++i) {
- int target = b[i];
- // 不断入栈,直到栈顶等于 target 或者所有元素都已入栈
- while (nextPush <= n && (top == -1 || st[top] != target)) {
- st[++top] = nextPush;
- if (print_ops) {
- printf("入栈 %d | 栈=", nextPush);
- print_stack(st, top);
- putchar('\n');
- }
- ++nextPush;
- }
- // 若此时栈顶是 target,则弹出;否则无法实现
- if (top != -1 && st[top] == target) {
- --top;
- if (print_ops) {
- printf("出栈 -> %d | 栈=", target);
- print_stack(st, top);
- putchar('\n');
- }
- } else {
- free(st);
- return 0; // 非法
- }
- }
- free(st);
- return 1; // 合法
- }
- int main(void) {
- int n;
- if (scanf("%d", &n) != 1) return 0;
- if (n < 0) return 0;
- int *b = (int *)malloc(sizeof(int) * (n > 0 ? n : 1));
- if (!b) {
- fprintf(stderr, "内存分配失败\n");
- return 1;
- }
- for (int i = 0; i < n; ++i) {
- if (scanf("%d", &b[i]) != 1) {
- free(b);
- return 0;
- }
- }
- // 先仅判定合法性
- int ok = simulate_and_maybe_print(b, n, 0);
- if (!ok) {
- printf("否:该 b 序列不是以 1..n 为进栈序列的合法出栈序列。\n");
- } else {
- printf("是:该 b 序列可以由进栈序列 1..n 通过单栈操作得到。\n");
- printf("操作过程:\n");
- // 再次模拟,并打印全过程
- simulate_and_maybe_print(b, n, 1);
- }
- free(b);
- return 0;
- }
复制代码 |
|