wyyy510 发表于 2025-10-23 18:30:43

求助

一个b序列的长度为n,其元素恰好是1到n的某个排列,编写一个实验程序判断b序列是否是以1,2,...,n为进栈序列的出栈序列,如果不是,输出相应的提示信息;如果是,输出由该进栈序列通过一个栈得到b序列的过程。求大神这个应该怎么写

FishC 发表于 2025-10-23 18:32:13

要判断序列 b 是否是以 1,2,...,n 为进栈序列的出栈序列,可以使用栈模拟的方法。基本思路是:用一个栈来模拟进栈和出栈操作,同时遍历序列 b,检查每个元素是否能通过合法的栈操作得到。

以下是具体的 Python 实现代码,包括输入处理、栈模拟和输出过程:


n = int(input("请输入n: "))
b = list(map(int, input("请输入序列b,用空格分隔: ").split()))

# 检查b是否是1到n的排列
if len(b) != n or set(b) != set(range(1, n+1)):
    print("错误:序列b不是1到n的排列")
else:
    stack = []
    current = 1# 下一个要进栈的数字
    operations = []# 记录操作过程
    i = 0# 指向b的索引

    while i < n:
      if stack and stack[-1] == b:
            # 栈顶元素匹配,出栈
            val = stack.pop()
            operations.append(f"pop {val}")
            i += 1
      elif current <= n:
            # 进栈下一个数字
            stack.append(current)
            operations.append(f"push {current}")
            current += 1
      else:
            # 无法匹配,退出循环
            break

    if i == n:
      print("是有效的出栈序列")
      print("过程:")
      for op in operations:
            print(op)
    else:
      print("不是有效的出栈序列")


使用说明:
1. 首先输入 n 的值。
2. 然后输入序列 b,元素之间用空格分隔。
3. 程序会检查 b 是否是 1 到 n 的排列,如果不是,会输出错误信息。
4. 如果是,程序会模拟栈操作,如果 b 是有效的出栈序列,则输出操作过程(包括 push 和 pop);否则输出提示信息。

示例:
- 如果输入 n=3,b=,输出会是:
是有效的出栈序列
过程:
push 1
push 2
pop 2
push 3
pop 3
pop 1

- 如果输入 n=3,b=,输出会是:
不是有效的出栈序列

这个程序通过栈模拟高效地解决了问题,代码简洁易懂。如果有任何疑问,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

小甲鱼的二师兄 发表于 2025-10-23 18:47:01

#include <stdio.h>
#include <stdlib.h>

/* 辅助函数:打印栈内容,形如 (自底向顶) */
static void print_stack(const int *st, int top) {
    putchar('[');
    for (int i = 0; i <= top; ++i) {
      if (i) printf(", ");
      printf("%d", st);
    }
    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;

      // 不断入栈,直到栈顶等于 target 或者所有元素都已入栈
      while (nextPush <= n && (top == -1 || st != target)) {
            st[++top] = nextPush;
            if (print_ops) {
                printf("入栈 %d | 栈=", nextPush);
                print_stack(st, top);
                putchar('\n');
            }
            ++nextPush;
      }

      // 若此时栈顶是 target,则弹出;否则无法实现
      if (top != -1 && st == 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) != 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;
}
页: [1]
查看完整版本: 求助