1.栈操作的合法性
假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合
法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数 n 和 m,其中 n 是待测序列的个数,m(≤50)是堆栈的最大容量。随后 n 行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过
100。
输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。
输入样例:
在这里给出一组输入。例如:
4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX
输出样例:
在这里给出相应的输出。例如:
YES
NO
NO
NO
C++代码:
#include<iostream>
using namespace std;
#define MAXS 101
#define MAXN 50
int S[MAXN],top,m;
int IsEmpty();
int IsFull();
int push();
int pop();
int main()
{
int i,j,n;
char str[MAXS];
cin>>n>>m;
for(i=0;i<n;i++)
{
cin>>str;
j=0;
top=-1;
while(str[j]!='\0')
{
if(str[j]=='S'&&!push())
{
break;
}
if(str[j]=='X'&&!pop())
{
break;
}
j++;
}
if(str[j]=='\0'&&IsEmpty())
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
int IsEmpty()
{
return (top==-1)? 1:0;
}
int IsFull()
{
return (top==m-1)? 1:0;
}
int push()
{
if(IsFull())
{
return 0;
}
else
{
S[top++]=1;
return 1;
}
}
int pop()
{
if(IsEmpty())
{
return 0;
}
else
{
top--;
return 1;
}
}
Python代码:
# 定义全局变量(对应C++的全局数组和变量,确保函数间数据共享)
MAX_N = 50 # 栈的最大容量上限(对应C++的MAXN)
S = [0] * MAX_N # 模拟栈的数组(存储占位值,C++中存1,Python无需实际存值,仅用top控制)
top = -1 # 栈顶指针(初始为-1,对应空栈)
m = 0 # 栈的实际最大容量(由输入指定)
def is_empty() -> int:
"""判断栈是否为空,对应C++的IsEmpty()
返回1表示空,0表示非空"""
return 1 if top == -1 else 0
def is_full() -> int:
"""判断栈是否已满,对应C++的IsFull()
返回1表示满,0表示未满"""
return 1 if top == m - 1 else 0
def push() -> int:
"""入栈操作(对应C++的push()),'S'触发该操作
返回1表示入栈成功,0表示栈满失败"""
global top # 声明修改全局变量top
if is_full():
return 0
else:
# C++中存1,Python无需实际存储值,仅移动栈顶指针即可(栈的核心是top控制)
top += 1
return 1
def pop() -> int:
"""出栈操作(对应C++的pop()),'X'触发该操作
返回1表示出栈成功,0表示栈空失败"""
global top # 声明修改全局变量top
if is_empty():
return 0
else:
top -= 1
return 1
def main():
global top, m # 声明使用全局变量
# 读取测试用例数量n和栈最大容量m(对应C++的cin>>n>>m)
n, m = map(int, input().split())
for _ in range(n):
# 读取当前待校验的字符串(对应C++的cin>>str)
s = input().strip()
j = 0 # 字符串索引指针
top = -1 # 每个测试用例重新初始化栈顶(空栈)
valid = True # 标记当前字符串是否仍可能合法
while j < len(s) and valid:
current_char = s[j]
if current_char == 'S':
# 遇到'S',执行入栈,若失败则标记不合法
if not push():
valid = False
elif current_char == 'X':
# 遇到'X',执行出栈,若失败则标记不合法
if not pop():
valid = False
# 其他字符(若存在)按原逻辑不处理,直接跳过(C++中仅处理'S'和'X')
j += 1
# 校验结果:字符串遍历完且栈为空 → 合法(YES),否则不合法(NO)
if valid and is_empty():
print("YES")
else:
print("NO")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
public class StackValidation {
// 常量定义(对应Python的全局变量定义)
private static final int MAX_N = 50; // 栈的最大容量上限
private static int[] S = new int[MAX_N]; // 模拟栈的数组
private static int top; // 栈顶指针
private static int m; // 栈的实际最大容量
/**
* 判断栈是否为空
* @return 1表示空,0表示非空
*/
private static int isEmpty() {
return (top == -1) ? 1 : 0;
}
/**
* 判断栈是否已满
* @return 1表示满,0表示未满
*/
private static int isFull() {
return (top == m - 1) ? 1 : 0;
}
/**
* 入栈操作(对应'S'字符)
* @return 1表示成功,0表示失败(栈满)
*/
private static int push() {
if (isFull() == 1) {
return 0;
} else {
S[++top] = 1; // 与C++保持一致,存入1
return 1;
}
}
/**
* 出栈操作(对应'X'字符)
* @return 1表示成功,0表示失败(栈空)
*/
private static int pop() {
if (isEmpty() == 1) {
return 0;
} else {
top--;
return 1;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取测试用例数量n和栈最大容量m
int n = scanner.nextInt();
m = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
for (int i = 0; i < n; i++) {
String str = scanner.nextLine().trim();
int j = 0;
top = -1; // 每个测试用例重新初始化栈顶
boolean valid = true;
while (j < str.length() && valid) {
char currentChar = str.charAt(j);
if (currentChar == 'S') {
// 处理入栈操作
if (push() == 0) {
valid = false;
}
} else if (currentChar == 'X') {
// 处理出栈操作
if (pop() == 0) {
valid = false;
}
}
j++;
}
// 判断结果并输出
if (valid && isEmpty() == 1) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
scanner.close();
}
}
2.Ackermann函数的非递归求值
任务描述
本关任务:
已知Ackermann函数定义如下:
写出计算Ack(m,n)的递归算法。
编程要求
输入
多组数据,每组数据有一行,为两个整数m和n。当m和n都等于0时,输入结束。
输出
每组数据输出一行,为Ack(m,n)。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
2 1
0 0
输出样例:
在这里给出相应的输出。例如:
5
C++代码:
#include<iostream>
using namespace std;
#define MAXSIZE 10000
int feidiguiAck(int m,int n);
int main()
{
while(1)
{
int m,n,t;
cin>>m>>n;
if(m==0&&n==0)
{
break;
}
t=feidiguiAck(m,n);
cout<<t<<endl;
}
return 0;
}
int feidiguiAck(int m,int n)
{
int i,j,a[m+1][MAXSIZE];
for(j=0;j<MAXSIZE;j++)
{
a[0][j]=j+1;
}
for(i=1;i<=m;i++)
{
a[i][0]=a[i-1][1];
for(j=1;j<MAXSIZE;j++)
{
a[i][j]=a[i-1][a[i][j-1]];
}
}
return (a[m][n]);
}
Python代码:
def feidigui_ack(m: int, n: int) -> int:
"""
非递归实现的Ackermann函数
根据Ackermann函数定义:
A(0, n) = n + 1
A(m, 0) = A(m-1, 1)
A(m, n) = A(m-1, A(m, n-1))
使用二维数组存储中间结果,避免递归调用
"""
MAXSIZE = 10000 # 对应C++中的宏定义MAXSIZE
# 创建(m+1)行的二维列表,每行初始化为0
# 由于Python列表动态性,无需预先分配MAXSIZE列,但为保持逻辑一致仍使用该大小
a = [[0] * MAXSIZE for _ in range(m + 1)]
# 处理m=0的情况:A(0, j) = j + 1
for j in range(MAXSIZE):
a[0][j] = j + 1
# 处理m >= 1的情况
for i in range(1, m + 1):
# 处理n=0的情况:A(i, 0) = A(i-1, 1)
a[i][0] = a[i-1][1]
# 处理n >= 1的情况:A(i, j) = A(i-1, A(i, j-1))
for j in range(1, MAXSIZE):
# 确保索引不超出范围(A(i, j-1)的结果作为下一个索引)
if a[i][j-1] < MAXSIZE:
a[i][j] = a[i-1][a[i][j-1]]
else:
# 超出预设范围时返回特殊值(实际Ackermann函数值增长极快,可能经常触发)
return -1 # 表示超出计算范围
return a[m][n]
def main():
while True:
try:
# 读取输入的m和n
m, n = map(int, input().split())
# 输入0 0时退出循环
if m == 0 and n == 0:
break
# 计算并输出结果
result = feidigui_ack(m, n)
print(result)
except Exception as e:
# 处理输入错误等异常情况
print(f"错误: {e}")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
public class Ackermann {
private static final int MAXSIZE = 10000; // 对应Python中的MAXSIZE常量
/**
* 非递归实现的Ackermann函数
* 根据Ackermann函数定义:
* A(0, n) = n + 1
* A(m, 0) = A(m-1, 1)
* A(m, n) = A(m-1, A(m, n-1))
* 使用二维数组存储中间结果,避免递归调用
*/
public static int feidiguiAck(int m, int n) {
// 创建(m+1)行MAXSIZE列的二维数组
int[][] a = new int[m + 1][MAXSIZE];
// 处理m=0的情况:A(0, j) = j + 1
for (int j = 0; j < MAXSIZE; j++) {
a[0][j] = j + 1;
}
// 处理m >= 1的情况
for (int i = 1; i <= m; i++) {
// 处理n=0的情况:A(i, 0) = A(i-1, 1)
a[i][0] = a[i - 1][1];
// 处理n >= 1的情况:A(i, j) = A(i-1, A(i, j-1))
for (int j = 1; j < MAXSIZE; j++) {
// 确保索引不超出范围(A(i, j-1)的结果作为下一个索引)
if (a[i][j - 1] < MAXSIZE) {
a[i][j] = a[i - 1][a[i][j - 1]];
} else {
// 超出预设范围时返回特殊值
return -1; // 表示超出计算范围
}
}
}
return a[m][n];
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
try {
// 读取输入的m和n
int m = scanner.nextInt();
int n = scanner.nextInt();
// 输入0 0时退出循环
if (m == 0 && n == 0) {
break;
}
// 计算并输出结果
int result = feidiguiAck(m, n);
System.out.println(result);
} catch (Exception e) {
// 处理输入错误等异常情况
System.out.println("错误: " + e.getMessage());
// 清除错误输入
if (scanner.hasNext()) {
scanner.next();
}
}
}
scanner.close();
}
}
3.Ackermann函数的递归求值
任务描述
本关任务:
已知Ackermann函数定义如下:
写出计算Ack(m,n)的递归算法。
编程要求
输入
多组数据,每组数据有一行,为两个整数m和n。当m和n都等于0时,输入结束。
输出
每组数据输出一行,为Ack(m,n)。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
3 5
3 10
0 0
输出样例:
在这里给出相应的输出。例如:
253
8189
C++代码:
#include<iostream>
using namespace std;
int diguiAck(int m,int n);
int main()
{
while(1)
{
int m,n,t;
cin>>m>>n;
if(m==0&&n==0)
{
break;
}
t=diguiAck(m,n);
cout<<t<<endl;
}
return 0;
}
int diguiAck(int m,int n)
{
if(m==0)
{
return n+1;
}
else if(m!=0&&n==0)
{
return diguiAck(m-1,1);
}
else if(m!=0&&n!=0)
{
return diguiAck(m-1,diguiAck(m,n-1));
}
}
Python代码:
def digui_ack(m: int, n: int) -> int:
"""
递归实现的Ackermann函数
根据定义:
- 若m=0,返回n+1
- 若m≠0且n=0,返回A(m-1, 1)
- 若m≠0且n≠0,返回A(m-1, A(m, n-1))
"""
if m == 0:
return n + 1
elif m != 0 and n == 0:
return digui_ack(m - 1, 1)
else: # m≠0且n≠0的情况
return digui_ack(m - 1, digui_ack(m, n - 1))
def main():
while True:
try:
# 读取输入的m和n
m, n = map(int, input().split())
# 输入0 0时退出循环
if m == 0 and n == 0:
break
# 计算并输出结果
result = digui_ack(m, n)
print(result)
except RecursionError:
# 处理递归深度超限(Ackermann函数增长极快,易触发)
print("递归深度超限,无法计算")
except Exception as e:
# 处理其他输入错误等异常
print(f"错误: {e}")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
/**
* 递归实现的 Ackermann 函数(复刻 Python 原逻辑)
* Ackermann 函数定义:
* 1. 当 m = 0 时,A(m, n) = n + 1
* 2. 当 m ≠ 0 且 n = 0 时,A(m, n) = A(m-1, 1)
* 3. 当 m ≠ 0 且 n ≠ 0 时,A(m, n) = A(m-1, A(m, n-1))
*/
public class RecursiveAckermann {
/**
* 递归计算 Ackermann 函数值
* @param m 函数第一个参数(非负整数)
* @param n 函数第二个参数(非负整数)
* @return 函数计算结果(int 类型,超出范围可能溢出)
*/
public static int diguiAck(int m, int n) {
if (m == 0) {
// 规则1:m=0时返回n+1
return n + 1;
} else if (m != 0 && n == 0) {
// 规则2:m≠0且n=0时,递归调用A(m-1, 1)
return diguiAck(m - 1, 1);
} else {
// 规则3:m≠0且n≠0时,嵌套递归调用A(m-1, A(m, n-1))
return diguiAck(m - 1, diguiAck(m, n - 1));
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 循环读取输入,直到输入 0 0 退出
while (true) {
try {
// 读取 m 和 n(复刻 Python 的 input().split() 逻辑)
System.out.print("请输入 m 和 n(空格分隔,输入 0 0 退出):");
String input = scanner.nextLine().trim();
String[] parts = input.split("\\s+"); // 支持任意数量空格分隔
// 校验输入格式(必须是两个整数)
if (parts.length != 2) {
throw new IllegalArgumentException("输入格式错误,需输入两个整数(如:2 3)");
}
int m = Integer.parseInt(parts[0]);
int n = Integer.parseInt(parts[1]);
// 退出条件:m=0 且 n=0
if (m == 0 && n == 0) {
System.out.println("程序已退出");
break;
}
// 计算并输出结果(复刻 Python 的 print(result))
int result = diguiAck(m, n);
System.out.println("Ackermann(" + m + ", " + n + ") = " + result);
} catch (StackOverflowError e) {
// 对应 Python 的 RecursionError(Java 中递归过深触发栈溢出)
System.out.println("错误:递归深度超限,无法计算(Ackermann 函数增长极快,建议 m ≤ 3)");
} catch (NumberFormatException e) {
// 处理非整数输入(如输入字母、小数)
System.out.println("错误:输入必须是整数(如:2 3),请重新输入");
} catch (IllegalArgumentException e) {
// 处理输入数量错误(如只输入1个值或3个值)
System.out.println("错误:" + e.getMessage());
} catch (Exception e) {
// 捕获其他未预期异常,避免程序崩溃
System.out.println("未知错误:" + e.getMessage());
}
}
// 关闭扫描器,释放资源(Java 资源管理规范)
scanner.close();
}
}
4.基于栈的可操作判断
任务描述
本关任务:假设I和O分别代表入栈和出栈操作。栈的始态和终态均为空。入栈和出栈的操作序列可以表示为仅由I和O组成的序列,称可操作的序列为合法序列,否则称为非法序列。请设计一个算法,判断所给的操作序列是否合法。若合法输出“true”,反之输出“false”。
编程要求
输入
多组数据,每组数据为一行长度不定的操作序列A。当A为“0”时,输入结束。
输出
对应每组数据输出一行。若序列A为合法序列输出“TRUE”,反之输出“FALSE”。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
IOIOIO
IIOOOO
0
输出样例:
在这里给出相应的输出。例如:
TRUE
FALSE
C++代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAXSIZE 100
//顺序栈
typedef char SElemType;
typedef struct {
SElemType *data; //栈底指针
int top; //栈顶指针
}SqStack;
void InitStack( SqStack &S ); //顺序栈初始化
bool StackEmpty( SqStack S ); //判断顺序栈是否为空
int StackLength( SqStack S ); //求顺序栈的长度
void ClearStack( SqStack S ); //清空顺序栈
void DestroyStack( SqStack &S ); //销毁顺序栈
void Push2( SqStack &S, SElemType e); //顺序栈进栈
SElemType Pop2( SqStack &S ); //顺序栈出栈
SElemType GetTop( SqStack S ); //取顺序栈栈顶元素
bool hefaxulie(char *str);//判断合法序列
int main()
{
while(1)
{
char str[100];
int i;
cin>>str;
for(i=0;str[i]!='\0';i++);
if(i==1&&str[0]=='0')
{
break;
}
if(hefaxulie(str))
{
cout<<"TRUE"<<endl;
}
else
{
cout<<"FALSE"<<endl;
}
}
return 0;
}
void InitStack( SqStack &S ) //顺序栈初始化
{
S.data=new SElemType[MAXSIZE];
S.top=0;
}
bool StackEmpty( SqStack S ) //判断顺序栈是否为空
{
return S.top==0;
}
void Push2( SqStack &S, SElemType e) //顺序栈进栈
{
if(S.top==MAXSIZE)
{
cout<<"栈满"<<endl;
}
else
{
S.data[S.top++]=e;
}
}
SElemType Pop2( SqStack &S ) //顺序栈出栈
{
if(S.top==0)
{
cout<<"栈空"<<endl;
return 0+'0';
}
return S.data[--S.top];
}
SElemType GetTop( SqStack S ) //取顺序栈栈顶元素
{
if(S.top==0)
{
cout<<"栈空"<<endl;
return 0+'0';
}
return S.data[S.top-1];
}
bool hefaxulie(char *str)
{
int i,a=0,b=0;
for(i=0;str[i]!='\0';i++)
{
if(str[i]=='I')
{
a++;
}
else if(str[i]=='O')
{
b++;
}
}
if(a!=b)
{
return false;
}
SqStack S;
InitStack(S);
for(i=0;str[i]!='\0';i++)
{
if(str[i]=='I')
{
Push2(S,str[i]);
}
else if(str[i]=='O')
{
Pop2(S);
}
}
if(S.top==0)
{
return true;
}
else
{
return false;
}
}
Python代码:
# 定义顺序栈类(对应C++的SqStack结构体,封装栈的所有操作)
class SqStack:
MAXSIZE = 100 # 对应C++的宏定义MAXSIZE
def __init__(self):
"""顺序栈初始化,对应C++的InitStack函数"""
self.data = [] # 用Python列表模拟栈存储(替代C++的SElemType*数组)
self.top = 0 # 栈顶指针(初始为0,与C++一致)
def is_empty(self) -> bool:
"""判断顺序栈是否为空,对应C++的StackEmpty函数"""
return self.top == 0
def push(self, e: str) -> None:
"""顺序栈进栈操作,对应C++的Push2函数"""
if self.top == self.MAXSIZE:
print("栈满")
else:
self.data.append(e) # 列表尾部添加元素(模拟入栈)
self.top += 1 # 栈顶指针后移
def pop(self) -> str:
"""顺序栈出栈操作,对应C++的Pop2函数"""
if self.top == 0:
print("栈空")
return chr(0 + ord('0')) # 对应C++的return 0+'0'(返回字符'0')
self.top -= 1 # 栈顶指针前移
return self.data.pop() # 列表尾部删除元素(模拟出栈)
def get_top(self) -> str:
"""取顺序栈栈顶元素,对应C++的GetTop函数"""
if self.top == 0:
print("栈空")
return chr(0 + ord('0'))
return self.data[self.top - 1] # 栈顶元素为列表倒数第1个元素
def clear(self) -> None:
"""清空顺序栈,对应C++的ClearStack函数(Python列表直接清空)"""
self.data.clear()
self.top = 0
def destroy(self) -> None:
"""销毁顺序栈,对应C++的DestroyStack函数(Python无需手动释放内存,简化为清空)"""
self.clear()
def hefaxulie(s: str) -> bool:
"""判断IO序列是否合法,对应C++的hefaxulie函数"""
a = 0 # 统计'I'的数量
b = 0 # 统计'O'的数量
# 第一步:统计I和O的总数,若不相等则直接不合法
for char in s:
if char == 'I':
a += 1
elif char == 'O':
b += 1
if a != b:
return False
# 第二步:用栈模拟IO操作,校验过程合法性
stack = SqStack() # 初始化栈
for char in s:
if char == 'I':
stack.push(char) # 遇到'I',执行入栈
elif char == 'O':
stack.pop() # 遇到'O',执行出栈
# 第三步:操作结束后栈为空则合法,否则不合法
return stack.top == 0
def main():
while True:
# 读取输入序列(对应C++的cin>>str)
s = input().strip()
# 退出条件:输入长度为1且字符是'0'(对应C++的i==1&&str[0]=='0')
if len(s) == 1 and s[0] == '0':
break
# 判断序列合法性并输出结果
if hefaxulie(s):
print("TRUE")
else:
print("FALSE")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
/**
* 顺序栈类(对应Python的SqStack类,封装栈的所有核心操作)
*/
class SqStack {
// 对应Python的MAXSIZE,栈的最大容量(与原C++宏定义一致)
private static final int MAXSIZE = 100;
// 存储栈元素的数组(替代Python的列表data)
private char[] data;
// 栈顶指针(初始为0,与Python的top逻辑完全一致)
private int top;
/**
* 顺序栈初始化(对应Python的__init__方法)
* 初始化数组容量并重置栈顶指针
*/
public SqStack() {
this.data = new char[MAXSIZE]; // 分配固定大小的数组空间
this.top = 0; // 栈顶指针初始化为0(空栈标志)
}
/**
* 判断栈是否为空(对应Python的is_empty方法)
* @return 空栈返回true,非空返回false
*/
public boolean isEmpty() {
return this.top == 0;
}
/**
* 入栈操作(对应Python的push方法)
* @param e 待入栈的字符(仅处理'I'或'O')
*/
public void push(char e) {
// 栈满判断(与Python的top == MAXSIZE逻辑一致)
if (this.top == MAXSIZE) {
System.out.println("栈满");
return;
}
// 元素入栈:先存值再移动指针(与Python的append+top++等效)
this.data[this.top] = e;
this.top++;
}
/**
* 出栈操作(对应Python的pop方法)
* @return 出栈的字符;栈空时返回'0'(与Python的return '0'逻辑一致)
*/
public char pop() {
// 栈空判断(与Python的top == 0逻辑一致)
if (this.top == 0) {
System.out.println("栈空");
return '0'; // 对应Python的chr(0 + ord('0'))
}
// 元素出栈:先移动指针再取值(与Python的top--+pop()等效)
this.top--;
return this.data[this.top];
}
/**
* 获取栈顶元素(对应Python的get_top方法)
* @return 栈顶字符;栈空时返回'0'
*/
public char getTop() {
if (this.top == 0) {
System.out.println("栈空");
return '0';
}
// 栈顶元素为top-1索引(与Python的data[top-1]逻辑一致)
return this.data[this.top - 1];
}
/**
* 清空栈(对应Python的clear方法)
* 重置栈顶指针即可(无需清空数组内容,逻辑上视为空栈)
*/
public void clear() {
this.top = 0;
}
/**
* 销毁栈(对应Python的destroy方法)
* Java中数组内存由JVM自动回收,简化为清空操作(与Python逻辑一致)
*/
public void destroy() {
this.clear();
}
/**
* 获取栈顶指针值(供外部判断栈是否为空,对应Python的stack.top)
* @return 栈顶指针top的值
*/
public int getTopPointer() {
return this.top;
}
}
/**
* IO序列合法性校验主类(包含核心校验逻辑与交互流程)
*/
public class IOSequenceValidation {
/**
* 判断IO序列是否合法(对应Python的hefaxulie函数)
* 校验规则:1. I和O总数相等;2. 栈模拟过程无非法出栈;3. 最终栈为空
* @param s 待校验的IO序列字符串
* @return 合法返回true,不合法返回false
*/
public static boolean hefaxulie(String s) {
int countI = 0; // 统计'I'的数量(对应Python的a)
int countO = 0; // 统计'O'的数量(对应Python的b)
// 第一步:统计I和O总数,总数不等直接判定不合法
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i); // 替代Python的for char in s
if (c == 'I') {
countI++;
} else if (c == 'O') {
countO++;
}
}
if (countI != countO) {
return false;
}
// 第二步:用栈模拟IO操作,校验过程合法性
SqStack stack = new SqStack(); // 初始化栈(对应Python的SqStack())
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == 'I') {
stack.push(c); // 遇'I'入栈(与Python的push一致)
} else if (c == 'O') {
stack.pop(); // 遇'O'出栈(与Python的pop一致)
}
}
// 第三步:操作结束后栈为空则合法(对应Python的stack.top == 0)
return stack.getTopPointer() == 0;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 替代Python的input()
// 循环读取输入,直到输入'0'退出(对应Python的while True)
while (true) {
// 读取输入并去除首尾空格(对应Python的input().strip())
String s = scanner.nextLine().trim();
// 退出条件:输入长度为1且字符是'0'(与Python逻辑完全一致)
if (s.length() == 1 && s.charAt(0) == '0') {
break;
}
// 判断序列合法性并输出结果(对应Python的print("TRUE"/"FALSE"))
if (hefaxulie(s)) {
System.out.println("TRUE");
} else {
System.out.println("FALSE");
}
}
scanner.close(); // 关闭扫描器,释放资源(Java资源管理规范)
}
}
5.基于栈的回文字符序列判断
任务描述
本关任务:回文序列是正反读均相同的字符序列,如“abba”和“abdba”均是回文,但是“good”不是回文。请设计一个算法判定给定的字符序列是否为回文。
编程要求
输入
多组数据,每组数据有一行。每一行为一个长度不定的字符序列A。当A为“0”时,输入结束。
输出
对于每组数据输出一行。若字符序列A是回文序列,则输出“YES”,否则输出“NO”。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
abba
abdba
good
0
输出样例:
在这里给出相应的输出。例如:
YES
YES
NO
C++代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAXSIZE 100
//顺序栈
typedef char SElemType;
typedef struct {
SElemType *data; //栈底指针
int top; //栈顶指针
}SqStack;
void InitStack( SqStack &S ); //顺序栈初始化
bool StackEmpty( SqStack S ); //判断顺序栈是否为空
int StackLength( SqStack S ); //求顺序栈的长度
void ClearStack( SqStack S ); //清空顺序栈
void DestroyStack( SqStack &S ); //销毁顺序栈
void Push2( SqStack &S, SElemType e); //顺序栈进栈
SElemType Pop2( SqStack &S ); //顺序栈出栈
SElemType GetTop( SqStack S ); //取顺序栈栈顶元素
bool huiwen(char *str); //判断回文串
int main()
{
while(1)
{
char str[100];
cin>>str;
int i;
for(i=0;str[i]!='\0';i++);
if(i==1&&str[0]=='0')
{
break;
}
if(huiwen(str))
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
void InitStack( SqStack &S ) //顺序栈初始化
{
S.data=new SElemType[MAXSIZE];
S.top=0;
}
bool StackEmpty( SqStack S ) //判断顺序栈是否为空
{
return S.top==0;
}
void Push2( SqStack &S, SElemType e) //顺序栈进栈
{
if(S.top==MAXSIZE)
{
cout<<"栈满"<<endl;
}
else
{
S.data[S.top++]=e;
}
}
SElemType Pop2( SqStack &S ) //顺序栈出栈
{
if(S.top==0)
{
cout<<"栈空"<<endl;
return 0+'0';
}
return S.data[--S.top];
}
SElemType GetTop( SqStack S ) //取顺序栈栈顶元素
{
if(S.top==0)
{
cout<<"栈空"<<endl;
return 0+'0';
}
return S.data[S.top-1];
}
bool huiwen(char *str)
{
int i,n=0;
for(i=0;str[i]!='\0';i++)
{
n++;
}
SqStack S;
InitStack(S);
for(i=0;i<(n/2);i++)
{
Push2(S,str[i]);
}
if(n%2==0)
{
for(i=n/2;i<n;i++)
{
if(GetTop(S)!=str[i])
{
return false;
}
Pop2(S);
}
}
else
{
for(i=n/2+1;i<n;i++)
{
if(GetTop(S)!=str[i])
{
return false;
}
Pop2(S);
}
}
return true;
}
Python代码:
# 定义顺序栈类(对应C++的SqStack结构体,封装栈的所有操作)
class SqStack:
MAXSIZE = 100 # 对应C++的宏定义MAXSIZE
def __init__(self):
"""顺序栈初始化,对应C++的InitStack函数"""
self.data = [] # 用Python列表模拟栈存储(替代C++的SElemType*数组)
self.top = 0 # 栈顶指针(初始为0,与C++一致)
def is_empty(self) -> bool:
"""判断顺序栈是否为空,对应C++的StackEmpty函数"""
return self.top == 0
def get_length(self) -> int:
"""求顺序栈的长度,对应C++的StackLength函数"""
return self.top
def push(self, e: str) -> None:
"""顺序栈进栈操作,对应C++的Push2函数"""
if self.top == self.MAXSIZE:
print("栈满")
else:
self.data.append(e) # 列表尾部添加元素(模拟入栈)
self.top += 1 # 栈顶指针后移
def pop(self) -> str:
"""顺序栈出栈操作,对应C++的Pop2函数"""
if self.top == 0:
print("栈空")
return chr(0 + ord('0')) # 对应C++的return 0+'0'(返回字符'0')
self.top -= 1 # 栈顶指针前移
return self.data.pop() # 列表尾部删除元素(模拟出栈)
def get_top(self) -> str:
"""取顺序栈栈顶元素,对应C++的GetTop函数"""
if self.top == 0:
print("栈空")
return chr(0 + ord('0'))
return self.data[self.top - 1] # 栈顶元素为列表倒数第1个元素
def clear(self) -> None:
"""清空顺序栈,对应C++的ClearStack函数"""
self.data.clear()
self.top = 0
def destroy(self) -> None:
"""销毁顺序栈,对应C++的DestroyStack函数(Python无需手动释放内存)"""
self.clear()
def huiwen(s: str) -> bool:
"""判断字符串是否为回文,对应C++的huiwen函数"""
n = len(s) # 计算字符串长度(替代C++的for循环统计长度)
stack = SqStack() # 初始化栈
# 第一步:将字符串前半部分字符入栈
for i in range(n // 2):
stack.push(s[i])
# 第二步:根据字符串长度奇偶性,对比后半部分与栈顶元素
if n % 2 == 0:
# 偶数长度:从n/2位置开始对比
start = n // 2
else:
# 奇数长度:跳过中间字符,从n/2+1位置开始对比
start = n // 2 + 1
# 遍历后半部分字符,与栈顶元素对比
for i in range(start, n):
if stack.get_top() != s[i]:
return False # 字符不匹配,不是回文
stack.pop() # 匹配成功,栈顶元素出栈
# 所有字符匹配完成,是回文
return True
def main():
while True:
# 读取输入字符串(对应C++的cin>>str)
s = input().strip()
# 退出条件:输入长度为1且字符是'0'(对应C++的i==1&&str[0]=='0')
if len(s) == 1 and s[0] == '0':
break
# 判断是否为回文并输出结果
if huiwen(s):
print("YES")
else:
print("NO")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
/**
* 顺序栈类(对应Python的SqStack类,封装栈的所有核心操作)
*/
class SqStack {
// 对应Python的MAXSIZE,栈的最大容量(与原C++宏定义一致)
private static final int MAXSIZE = 100;
// 存储栈元素的字符数组(替代Python的列表data)
private char[] data;
// 栈顶指针(初始为0,与Python的top逻辑完全一致)
private int top;
/**
* 顺序栈初始化(对应Python的__init__方法)
* 分配数组空间并重置栈顶指针
*/
public SqStack() {
this.data = new char[MAXSIZE]; // 初始化固定大小的字符数组
this.top = 0; // 栈顶指针初始化为0(空栈标志)
}
/**
* 判断栈是否为空(对应Python的is_empty方法)
* @return 空栈返回true,非空返回false
*/
public boolean isEmpty() {
return this.top == 0;
}
/**
* 求栈的长度(对应Python的get_length方法)
* @return 栈中元素的个数(即栈顶指针值)
*/
public int getLength() {
return this.top;
}
/**
* 入栈操作(对应Python的push方法)
* @param e 待入栈的字符(回文判断中为字符串的字符)
*/
public void push(char e) {
// 栈满判断(与Python的top == MAXSIZE逻辑一致)
if (this.top == MAXSIZE) {
System.out.println("栈满");
return;
}
// 元素入栈:先存值再移动栈顶指针(与Python的append+top++等效)
this.data[this.top] = e;
this.top++;
}
/**
* 出栈操作(对应Python的pop方法)
* @return 出栈的字符;栈空时返回'0'(与Python的return '0'逻辑一致)
*/
public char pop() {
// 栈空判断(与Python的top == 0逻辑一致)
if (this.top == 0) {
System.out.println("栈空");
return '0'; // 对应Python的chr(0 + ord('0'))
}
// 元素出栈:先移动指针再取值(与Python的top--+pop()等效)
this.top--;
return this.data[this.top];
}
/**
* 获取栈顶元素(对应Python的get_top方法)
* @return 栈顶字符;栈空时返回'0'
*/
public char getTop() {
if (this.top == 0) {
System.out.println("栈空");
return '0';
}
// 栈顶元素为top-1索引位置(与Python的data[top-1]逻辑一致)
return this.data[this.top - 1];
}
/**
* 清空栈(对应Python的clear方法)
* 重置栈顶指针即可(无需清空数组内容,逻辑上视为空栈)
*/
public void clear() {
this.top = 0;
}
/**
* 销毁栈(对应Python的destroy方法)
* Java中数组内存由JVM自动回收,简化为清空操作(与Python逻辑一致)
*/
public void destroy() {
this.clear();
}
}
/**
* 栈判断回文串主类(包含回文判断逻辑与交互流程)
*/
public class PalindromeChecker {
/**
* 判断字符串是否为回文(对应Python的huiwen函数)
* 核心逻辑:前半字符入栈,后半字符与栈顶对比
* @param s 待判断的字符串
* @return 是回文返回true,否则返回false
*/
public static boolean huiwen(String s) {
int n = s.length(); // 计算字符串长度(对应Python的len(s))
SqStack stack = new SqStack(); // 初始化栈(对应Python的SqStack())
// 第一步:将字符串前半部分字符入栈
for (int i = 0; i < n / 2; i++) {
stack.push(s.charAt(i)); // 取字符入栈(对应Python的s[i])
}
// 第二步:确定后半部分对比的起始位置(处理奇偶长度)
int start;
if (n % 2 == 0) {
// 偶数长度:从n/2位置开始对比
start = n / 2;
} else {
// 奇数长度:跳过中间字符,从n/2+1位置开始对比
start = n / 2 + 1;
}
// 第三步:遍历后半部分字符,与栈顶元素对比
for (int i = start; i < n; i++) {
if (stack.getTop() != s.charAt(i)) {
return false; // 字符不匹配,不是回文
}
stack.pop(); // 匹配成功,栈顶元素出栈
}
// 所有字符匹配完成,是回文
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 替代Python的input()
// 循环读取输入,直到输入'0'退出(对应Python的while True)
while (true) {
// 读取输入字符串并去除首尾空格(对应Python的input().strip())
String s = scanner.nextLine().trim();
// 退出条件:输入长度为1且字符是'0'(与Python逻辑完全一致)
if (s.length() == 1 && s.charAt(0) == '0') {
break;
}
// 判断是否为回文并输出结果(对应Python的print("YES"/"NO"))
if (huiwen(s)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
scanner.close(); // 关闭扫描器,释放资源(Java资源管理规范)
}
}
6.双栈的基本操作
任务描述
本关任务:将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端。当第0号栈的栈顶指针top[0]等于-1时该栈为空;当第1号栈的栈顶指针top[1]等于m时,该栈为空。两个栈均从两端向中间增长(见下图)。试编写双栈初始化,判断栈空、栈满、进栈和出栈算法的函数。函数调用次序依次为:进栈、栈满的判断、出栈、栈空的判断。
双栈数据结构的定义如下:
typedef struct
{
int top[2], bot[2]; //栈顶和栈底指针
SElemType *V; //栈数组
int m; //栈最大可容纳元素个数
}DblStack;
编程要求
输入
多组数据,每组数据有四行,每行的数据之间均用空格分隔。第一行为一个整数m,表示数组V的大小,第二行为四个整数e0、e1、d0、d1,e0和e1分别代表压入0号栈和1号栈的整数序列E0和E1的长度(依次连续入栈,中间没有出栈的情况),d0和d1分别代表从0号栈和1号栈弹出的序列的长度(依次连续出栈,中间没有入栈的情况)。第三行和第四行分别表示序列E0和E1。当m=0时,输入结束。
输出
对于每组数据输出三行。第一行代表进栈操作完成时栈是否为满(出栈操作尚未执行),栈满输出1,栈不满输出0。第二行和第三行的数据分别对应0号栈和1号栈。第二行包括d0+1个整数,其中前d0个整数代表出栈序列D0,最后一个整数代表出栈操作完成时0号栈是否为空,栈空输出0,不空输出1。第三行包括d1+1个整数,其中前d1个整数代表出栈序列D1,最后一个整数代表出栈操作完成时1号栈是否为空,栈空输出0,不空输出1。整数之间用空格分隔。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
7
3 4 2 2
1 2 3
2 3 4 5
12
4 6 4 3
1 3 4 5
1 3 5 6 8 1
0
输出样例:
在这里给出相应的输出。例如:
1
3 2 1
5 4 1
0
5 4 3 1 0
1 8 6 1
C++代码:
#include<iostream>
using namespace std;
#define MAXOP 100 //操作序列可能的最大长度
#define INFINITY 1e9 //代表正无穷
#define ERROR 0
#define MAXQSIZE 100
#define MAXSIZE 100
typedef int ElemType;
typedef struct
{
int top[2], bot[2];
ElemType *V;
int m;
}DblStack;
bool Init(DblStack *s);//初始化
int Push(DblStack *s,int a,int b);//入栈
ElemType Pop(DblStack *s,int a);//出栈
bool Empty(DblStack *s);//判断是否为空栈
int main()
{
int a,b,c,d,i,n,mm;
while(1)
{
DblStack s;
cin>>mm;
s.V=new ElemType[mm+1];
if(mm==0)
{
break;
}
s.m=mm;
Init(&s);
cin>>a>>b>>c>>d;
for(i=0;i<a;i++)
{
cin>>n;
Push(&s,0,n);
}
for(i=0;i<b;i++)
{
cin>>n;
Push(&s,1,n);
}
if(s.top[1]-s.top[0]==1)
{
cout<<"1"<<endl;
}
else
{
cout<<"0"<<endl;
}
for(i=0;i<c;i++)
{
cout<<Pop(&s,0)<<" ";
if(i==c-1)
{
if(s.top[0]==-1)
{
cout<<"0"<<endl;
}
else
{
cout<<"1"<<endl;
}
}
}
for(i=0;i<d;i++)
{
cout<<Pop(&s,1)<<" ";
if(i==d-1)
{
if(s.top[1]==s.m)
{
cout<<"0"<<endl;
}
else
{
cout<<"1"<<endl;
}
}
}
delete[] s.V;
}
return 0;
}
bool Init(DblStack *s)//初始化
{
s->top[0]=-1;
s->top[1]=s->m;
s->bot[0]=0;
s->bot[1]=s->m-1;
return true;
}
int Push(DblStack *s,int a,int b)//入栈
{
if(s->top[1]-s->top[0]==1)
{
cout<<"1"<<endl;
return 0;
}
switch(a)
{
case 0:
s->V[++s->top[0]]=b;
return 1;
break;
case 1:
s->V[--s->top[1]]=b;
return 1;
break;
default:
cout<<"错误栈"<<endl;
return 0;
break;
}
}
ElemType Pop(DblStack *s,int a)//出栈
{
switch(a)
{
case 0:
if(s->top[0]==-1)
{
cout<<"左栈为空"<<endl;
return ERROR;
}
else
{
return s->V[s->top[0]--];
}
break;
case 1:
if(s->top[1]==s->m)
{
cout<<"右栈为空"<<endl;
return ERROR;
}
else
{
return s->V[s->top[1]++];
}
break;
default :
break;
}
}
bool Empty(DblStack *s)//判断是否为空栈
{
return (s->top[0]==-1&&s->top[1]==s->m);
}
Python代码:
# 定义双栈类(对应C++的DblStack结构体,封装双栈所有操作)
class DblStack:
ERROR = 0 # 对应C++的ERROR,出栈失败返回值
def __init__(self, m: int):
"""
双栈初始化(对应C++的Init函数)
:param m: 双栈共享数组的最大容量(对应C++的s->m)
"""
self.m = m # 共享数组最大容量
self.V = [0] * (m + 1) # 共享数组(对应C++的ElemType* V,长度m+1与原逻辑一致)
self.top = [-1, m] # 双栈栈顶指针:top[0]左栈顶,top[1]右栈顶(初始值与C++一致)
self.bot = [0, m - 1] # 双栈栈底指针:bot[0]左栈底,bot[1]右栈底(初始值与C++一致)
def push(self, a: int, b: int) -> int:
"""
双栈入栈操作(对应C++的Push函数)
:param a: 栈编号(0=左栈,1=右栈)
:param b: 待入栈的元素值
:return: 1=入栈成功,0=入栈失败(栈满)
"""
# 判断双栈是否已满(左右栈顶指针相邻,对应C++的s->top[1]-s->top[0]==1)
if self.top[1] - self.top[0] == 1:
print("1") # 原C++栈满时输出1,保持逻辑一致
return 0
# 按栈编号执行入栈
if a == 0:
# 左栈入栈:栈顶指针先+1再存值(对应C++的s->V[++s->top[0]]=b)
self.top[0] += 1
self.V[self.top[0]] = b
return 1
elif a == 1:
# 右栈入栈:栈顶指针先-1再存值(对应C++的s->V[--s->top[1]]=b)
self.top[1] -= 1
self.V[self.top[1]] = b
return 1
else:
# 非法栈编号(对应C++的default分支)
print("错误栈")
return 0
def pop(self, a: int) -> int:
"""
双栈出栈操作(对应C++的Pop函数)
:param a: 栈编号(0=左栈,1=右栈)
:return: 出栈元素值;出栈失败(栈空)返回ERROR(0)
"""
if a == 0:
# 左栈出栈:判断左栈是否为空(对应C++的s->top[0]==-1)
if self.top[0] == -1:
print("左栈为空")
return self.ERROR
else:
# 先取值再将栈顶指针-1(对应C++的s->V[s->top[0]--])
val = self.V[self.top[0]]
self.top[0] -= 1
return val
elif a == 1:
# 右栈出栈:判断右栈是否为空(对应C++的s->top[1]==s->m)
if self.top[1] == self.m:
print("右栈为空")
return self.ERROR
else:
# 先取值再将栈顶指针+1(对应C++的s->V[s->top[1]++])
val = self.V[self.top[1]]
self.top[1] += 1
return val
else:
# 非法栈编号,返回错误值
return self.ERROR
def is_empty(self) -> bool:
"""判断双栈是否均为空(对应C++的Empty函数)"""
return self.top[0] == -1 and self.top[1] == self.m
def main():
while True:
# 读取双栈共享数组最大容量mm(对应C++的cin>>mm)
mm = int(input().strip())
# 退出条件:mm==0(对应C++的if(mm==0) break)
if mm == 0:
break
# 初始化双栈(替代C++的DblStack s; Init(&s); s.m=mm; s.V=new ElemType[mm+1])
dbl_stack = DblStack(mm)
# 读取a、b、c、d(对应C++的cin>>a>>b>>c>>d)
# a=左栈入栈元素个数,b=右栈入栈元素个数,c=左栈出栈元素个数,d=右栈出栈元素个数
a, b, c, d = map(int, input().split())
# 左栈入栈a个元素(对应C++的for(i=0;i<a;i++) {cin>>n; Push(&s,0,n);})
for _ in range(a):
n = int(input().strip())
dbl_stack.push(0, n)
# 右栈入栈b个元素(对应C++的for(i=0;i<b;i++) {cin>>n; Push(&s,1,n);})
for _ in range(b):
n = int(input().strip())
dbl_stack.push(1, n)
# 判断双栈是否已满(输出1=满,0=未满,对应C++的cout<<(s.top[1]-s.top[0]==1?"1":"0")<<endl;)
print("1" if dbl_stack.top[1] - dbl_stack.top[0] == 1 else "0")
# 左栈出栈c个元素(对应C++的for(i=0;i<c;i++) {cout<<Pop(&s,0)<<" "; ...})
for i in range(c):
pop_val = dbl_stack.pop(0)
print(pop_val, end=" ")
# 最后一个出栈元素后,输出左栈是否为空(0=空,1=非空)
if i == c - 1:
# 左栈空判断:top[0]==-1(对应C++的s.top[0]==-1)
print("0" if dbl_stack.top[0] == -1 else "1")
# 右栈出栈d个元素(对应C++的for(i=0;i<d;i++) {cout<<Pop(&s,1)<<" "; ...})
for i in range(d):
pop_val = dbl_stack.pop(1)
print(pop_val, end=" ")
# 最后一个出栈元素后,输出右栈是否为空(0=空,1=非空)
if i == d - 1:
# 右栈空判断:top[1]==mm(对应C++的s.top[1]==s.m)
print("0" if dbl_stack.top[1] == mm else "1")
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
/**
* 双栈类(对应Python的DblStack类,封装双栈所有核心操作)
*/
class DblStack {
public static final int ERROR = 0; // 对应Python的ERROR,出栈失败返回值
private int m; // 双栈共享数组的最大容量(对应Python的self.m)
private int[] V; // 共享数组(对应Python的self.V,存储双栈元素)
private int[] top; // 双栈栈顶指针:top[0]左栈顶,top[1]右栈顶
private int[] bot; // 双栈栈底指针:bot[0]左栈底,bot[1]右栈底
/**
* 双栈初始化(对应Python的__init__方法)
* @param m 共享数组最大容量
*/
public DblStack(int m) {
this.m = m;
this.V = new int[m + 1]; // 数组长度m+1,与Python的[0]*(m+1)一致
this.top = new int[]{-1, m}; // 左栈顶初始-1,右栈顶初始m(与Python一致)
this.bot = new int[]{0, m - 1}; // 左栈底0,右栈底m-1(与Python一致)
}
/**
* 双栈入栈操作(对应Python的push方法)
* @param a 栈编号:0=左栈,1=右栈
* @param b 待入栈的元素值
* @return 1=入栈成功,0=入栈失败(栈满)
*/
public int push(int a, int b) {
// 判断双栈是否已满(左右栈顶指针相邻,对应Python的top[1]-top[0]==1)
if (this.top[1] - this.top[0] == 1) {
System.out.println("1"); // 栈满时输出1,与Python逻辑一致
return 0;
}
// 按栈编号执行入栈
if (a == 0) {
// 左栈入栈:栈顶指针先+1再存值(对应Python的top[0]++ + V[top[0]]=b)
this.top[0]++;
this.V[this.top[0]] = b;
return 1;
} else if (a == 1) {
// 右栈入栈:栈顶指针先-1再存值(对应Python的top[1]-- + V[top[1]]=b)
this.top[1]--;
this.V[this.top[1]] = b;
return 1;
} else {
// 非法栈编号,输出错误提示
System.out.println("错误栈");
return 0;
}
}
/**
* 双栈出栈操作(对应Python的pop方法)
* @param a 栈编号:0=左栈,1=右栈
* @return 出栈元素值;栈空时返回ERROR(0)
*/
public int pop(int a) {
if (a == 0) {
// 左栈出栈:判断左栈是否为空(top[0]==-1)
if (this.top[0] == -1) {
System.out.println("左栈为空");
return ERROR;
}
// 先取值再移动栈顶指针(对应Python的val=V[top[0]] + top[0]--)
int val = this.V[this.top[0]];
this.top[0]--;
return val;
} else if (a == 1) {
// 右栈出栈:判断右栈是否为空(top[1]==m)
if (this.top[1] == this.m) {
System.out.println("右栈为空");
return ERROR;
}
// 先取值再移动栈顶指针(对应Python的val=V[top[1]] + top[1]++)
int val = this.V[this.top[1]];
this.top[1]++;
return val;
} else {
// 非法栈编号,返回错误值
return ERROR;
}
}
/**
* 判断双栈是否均为空(对应Python的is_empty方法)
* @return 双栈均空返回true,否则false
*/
public boolean isEmpty() {
return this.top[0] == -1 && this.top[1] == this.m;
}
// getter方法:供外部访问top指针(主逻辑需判断栈满和栈空)
public int[] getTop() {
return this.top;
}
// getter方法:供外部访问共享数组容量m(右栈空判断需用到)
public int getM() {
return this.m;
}
}
/**
* 双栈操作主类(包含交互流程与输入输出逻辑)
*/
public class DoubleStackMain {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 循环执行,直到输入mm=0退出(对应Python的while True)
while (true) {
// 读取双栈共享数组最大容量mm(对应Python的mm=int(input().strip()))
System.out.print(""); // 保持输入交互一致性,无额外提示
int mm = scanner.nextInt();
scanner.nextLine(); // 吸收nextInt()后的换行符,避免后续读取异常
// 退出条件:mm==0(对应Python的if mm==0: break)
if (mm == 0) {
break;
}
// 初始化双栈(对应Python的dbl_stack = DblStack(mm))
DblStack dblStack = new DblStack(mm);
// 读取a、b、c、d(对应Python的a,b,c,d = map(int, input().split()))
// a=左栈入栈数,b=右栈入栈数,c=左栈出栈数,d=右栈出栈数
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
int d = scanner.nextInt();
scanner.nextLine(); // 吸收换行符
// 左栈入栈a个元素(对应Python的for _ in range(a): push(0, n))
for (int i = 0; i < a; i++) {
int n = scanner.nextInt();
scanner.nextLine();
dblStack.push(0, n);
}
// 右栈入栈b个元素(对应Python的for _ in range(b): push(1, n))
for (int i = 0; i < b; i++) {
int n = scanner.nextInt();
scanner.nextLine();
dblStack.push(1, n);
}
// 判断双栈是否已满,输出1=满,0=未满(对应Python的print("1" if ... else "0"))
int[] top = dblStack.getTop();
System.out.println(top[1] - top[0] == 1 ? "1" : "0");
// 左栈出栈c个元素(对应Python的for i in range(c): pop(0))
for (int i = 0; i < c; i++) {
int popVal = dblStack.pop(0);
System.out.print(popVal + " ");
// 最后一个出栈元素后,输出左栈是否为空(0=空,1=非空)
if (i == c - 1) {
System.out.println(top[0] == -1 ? "0" : "1");
}
}
// 右栈出栈d个元素(对应Python的for i in range(d): pop(1))
for (int i = 0; i < d; i++) {
int popVal = dblStack.pop(1);
System.out.print(popVal + " ");
// 最后一个出栈元素后,输出右栈是否为空(0=空,1=非空)
if (i == d - 1) {
System.out.println(top[1] == dblStack.getM() ? "0" : "1");
}
}
}
scanner.close(); // 关闭扫描器,释放资源(Java资源管理规范)
}
}
7.入栈和出栈的基本操作
任务描述
本关任务:输入一个整数序列a1,a2,a3...,an。当ai不等于-1时将ai进栈;当ai=-1时,输出栈顶元素并将其出栈。
编程要求
输入
多组数据,每组数据有两行,第一行为序列的长度n,第二行为n个整数,整数之间用空格分隔。当n=0时输入结束。
输出
对于每一组数据输出若干行。每行为相应的出栈元素。当出栈异常时,输出“POP ERROR”并结束本组数据的输出。
测试说明
平台会对你编写的代码进行测试:
输入样例:
在这里给出一组输入。例如:
5
1 2 -1 -1 1
5
1 -1 -1 2 2
0
输出样例:
在这里给出相应的输出。例如:
2
1
1
POP ERROR
C++代码:
#include<iostream>
using namespace std;
#define MAXOP 100 //操作序列可能的最大长度
#define INFINITY 1e9 //代表正无穷
#define ERROR 0
#define MAXQSIZE 100
#define MAXSIZE 100
//顺序栈
typedef int SElemType;
typedef struct {
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈的最大容量
}SqStack;
void InitStack( SqStack &S ); //顺序栈初始化
bool StackEmpty( SqStack S ); //判断顺序栈是否为空
int StackLength( SqStack S ); //求顺序栈的长度
void ClearStack( SqStack S ); //清空顺序栈
void DestroyStack( SqStack &S ); //销毁顺序栈
void Push2( SqStack &S, SElemType e); //顺序栈进栈
SElemType Pop2( SqStack &S ); //顺序栈出栈
SElemType GetTop( SqStack S ); //取顺序栈栈顶元素
int main()
{
int c[1000],i,d;
while(1)
{
SqStack S;
InitStack(S);
cin>>d;
if(d==0)
{
break;
}
for(i=0;i<d;i++)
{
cin>>c[i];
}
for(i=0;i<d;i++)
{
if(c[i]!=-1)
{
Push2(S,c[i]);
}
else
{
if(S.base!=S.top)
{
cout<<GetTop(S)<<endl;
Pop2(S);
}
else //栈空时则跳出循环
{
cout<<"POP ERROR"<<endl;
break;
}
}
}
}
return 0;
}
void InitStack( SqStack &S ) //顺序栈初始化
{
S.base=new SElemType[MAXSIZE];
S.top=S.base;
S.stacksize=MAXSIZE;
}
bool StackEmpty( SqStack S ) //判断顺序栈是否为空
{
return S.base==S.top;
}
int StackLength( SqStack S ) //求顺序栈的长度
{
return S.top-S.base;
}
void ClearStack( SqStack S ) //清空顺序栈
{
if(S.base)
{
S.top=S.base;
}
}
void DestroyStack( SqStack &S ) //销毁顺序栈
{
if(S.base)
{
delete[] S.base;
S.stacksize=0;
S.base=S.top=NULL;
}
}
void Push2( SqStack &S, SElemType e) //顺序栈进栈
{
if(S.top-S.base==S.stacksize)
{
cout<<"栈满"<<endl;
}
else
{
*S.top++=e;
}
}
SElemType Pop2( SqStack &S ) //顺序栈出栈
{
if(S.base==S.top)
{
cout<<"栈空"<<endl;
}
else
{
int e=*--S.top;
return e;
}
}
SElemType GetTop( SqStack S ) //取顺序栈栈顶元素
{
if(S.base==S.top)
{
cout<<"栈空"<<endl;
}
else
{
int e=*(S.top-1);
return e;
}
}
Python代码:
# 定义顺序栈类(对应C++的SqStack结构体,封装栈的所有核心操作)
class SqStack:
MAXSIZE = 100 # 对应C++的宏定义MAXSIZE,栈的最大容量
ERROR = 0 # 对应C++的ERROR,仅作为逻辑占位(原C++未实际使用该值处理错误)
def __init__(self):
"""
顺序栈初始化(对应C++的InitStack函数)
用列表模拟栈存储,栈底固定为列表起始端,栈顶由top指针标记
"""
self.base = [] # 栈底(对应C++的SElemType* base,列表模拟数组)
self.top = 0 # 栈顶指针(初始与栈底重合,对应C++的S.top = S.base)
self.stacksize = self.MAXSIZE # 栈的最大容量
def is_empty(self) -> bool:
"""判断栈是否为空(对应C++的StackEmpty函数)"""
return self.top == 0 # 栈顶指针与栈底重合(top=0)即为空,对应C++的S.base==S.top
def get_length(self) -> int:
"""求栈的长度(对应C++的StackLength函数)"""
return self.top # 栈长度=栈顶指针值,对应C++的S.top - S.base
def clear(self) -> None:
"""清空栈(对应C++的ClearStack函数)"""
if self.base: # 栈底非空时执行清空
self.top = 0 # 重置栈顶指针即可,无需清空列表内容(逻辑上视为空栈)
def destroy(self) -> None:
"""销毁栈(对应C++的DestroyStack函数)"""
if self.base:
self.base.clear() # 清空列表(释放存储)
self.stacksize = 0 # 重置最大容量
self.top = 0 # 重置栈顶指针
def push(self, e: int) -> None:
"""顺序栈进栈操作(对应C++的Push2函数)"""
# 判断栈是否已满:栈长度==最大容量,对应C++的S.top-S.base==S.stacksize
if self.get_length() == self.stacksize:
print("栈满")
return
# 入栈:列表尾部添加元素,栈顶指针+1(对应C++的*S.top++=e)
self.base.append(e)
self.top += 1
def pop(self) -> int:
"""顺序栈出栈操作(对应C++的Pop2函数)"""
if self.is_empty(): # 判断栈空,对应C++的S.base==S.top
print("栈空")
return self.ERROR # 栈空返回错误值,对应C++的逻辑
# 出栈:栈顶指针-1,再从列表尾部取元素(对应C++的*--S.top)
self.top -= 1
return self.base.pop()
def get_top(self) -> int:
"""取栈顶元素(对应C++的GetTop函数)"""
if self.is_empty(): # 判断栈空
print("栈空")
return self.ERROR # 栈空返回错误值
# 栈顶元素为列表第top-1个索引(对应C++的*(S.top-1))
return self.base[self.top - 1]
def main():
while True:
# 初始化栈(对应C++的SqStack S; InitStack(S);)
stack = SqStack()
# 读取序列长度d(对应C++的cin>>d)
d = int(input().strip())
# 退出条件:d==0(对应C++的if(d==0) break)
if d == 0:
break
# 读取d个整数存入数组c(对应C++的for(i=0;i<d;i++) cin>>c[i];)
c = list(map(int, input().split()))
# 确保输入的整数个数与d一致(兼容可能的输入格式问题)
if len(c) != d:
# 若输入个数不匹配,按C++逻辑处理(仅读取前d个,或提示错误,此处按原逻辑忽略多余/补全缺失)
# 为严格对齐C++,假设输入始终正确,此处仅做简单处理
c = c[:d] + [0]*(d - len(c))
# 处理序列:遇非-1入栈,遇-1出栈并打印栈顶(对应C++的核心循环)
for num in c:
if num != -1:
# 非-1则入栈(对应C++的Push2(S,c[i]);)
stack.push(num)
else:
# -1则出栈:先判断栈是否空(对应C++的if(S.base!=S.top))
if not stack.is_empty():
# 打印栈顶元素,再出栈(对应C++的cout<<GetTop(S)<<endl; Pop2(S);)
print(stack.get_top())
stack.pop()
else:
# 栈空时输出错误提示并跳出循环(对应C++的cout<<"POP ERROR"<<endl; break;)
print("POP ERROR")
break
if __name__ == "__main__":
main()
Java代码:
import java.util.Scanner;
/**
* 顺序栈类(对应Python的SqStack类,封装栈的所有核心操作)
*/
public class SqStack {
public static final int MAXSIZE = 100; // 对应Python的MAXSIZE,栈的最大容量
public static final int ERROR = 0; // 对应Python的ERROR,错误处理返回值
private int[] base; // 栈底数组(对应Python的self.base列表)
private int top; // 栈顶指针(初始与栈底重合)
private int stacksize; // 栈的最大容量
/**
* 顺序栈初始化(对应Python的__init__方法)
*/
public SqStack() {
base = new int[MAXSIZE]; // 初始化栈底数组,容量为MAXSIZE
top = 0; // 栈顶指针初始化为0(与栈底重合)
stacksize = MAXSIZE; // 设置栈的最大容量
}
/**
* 判断栈是否为空(对应Python的is_empty方法)
* @return 栈空返回true,否则返回false
*/
public boolean isEmpty() {
return top == 0; // 栈顶指针为0表示栈空,对应Python的self.top == 0
}
/**
* 求栈的长度(对应Python的get_length方法)
* @return 栈中元素的个数
*/
public int getLength() {
return top; // 栈长度等于栈顶指针值,对应Python的self.top
}
/**
* 清空栈(对应Python的clear方法)
*/
public void clear() {
if (base != null) {
top = 0; // 重置栈顶指针即可,逻辑上视为空栈
}
}
/**
* 销毁栈(对应Python的destroy方法)
*/
public void destroy() {
if (base != null) {
base = null; // 释放数组引用
stacksize = 0; // 重置最大容量
top = 0; // 重置栈顶指针
}
}
/**
* 顺序栈进栈操作(对应Python的push方法)
* @param e 待入栈的元素
*/
public void push(int e) {
// 判断栈是否已满:栈长度等于最大容量
if (getLength() == stacksize) {
System.out.println("栈满");
return;
}
// 入栈:将元素存入数组,栈顶指针加1
base[top] = e;
top++;
}
/**
* 顺序栈出栈操作(对应Python的pop方法)
* @return 出栈的元素;栈空时返回ERROR
*/
public int pop() {
if (isEmpty()) { // 判断栈是否为空
System.out.println("栈空");
return ERROR;
}
// 出栈:栈顶指针减1,返回对应的元素
top--;
return base[top];
}
/**
* 取栈顶元素(对应Python的get_top方法)
* @return 栈顶元素;栈空时返回ERROR
*/
public int getTop() {
if (isEmpty()) { // 判断栈是否为空
System.out.println("栈空");
return ERROR;
}
// 返回栈顶元素(top-1位置的元素)
return base[top - 1];
}
}
/**
* 主类,处理输入输出和栈操作的核心逻辑
*/
public class StackMain {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
// 初始化栈(对应Python的stack = SqStack())
SqStack stack = new SqStack();
// 读取序列长度d(对应Python的d = int(input().strip()))
int d = scanner.nextInt();
scanner.nextLine(); // 吸收换行符
// 退出条件:d == 0(对应Python的if d == 0: break)
if (d == 0) {
break;
}
// 读取d个整数存入数组c(对应Python的c = list(map(int, input().split())))
int[] c = new int[d];
String[] inputParts = scanner.nextLine().split(" ");
for (int i = 0; i < d; i++) {
// 确保输入不足时用0填充,与Python处理逻辑一致
if (i < inputParts.length) {
c[i] = Integer.parseInt(inputParts[i]);
} else {
c[i] = 0;
}
}
// 处理序列:遇非-1入栈,遇-1出栈并打印栈顶
for (int num : c) {
if (num != -1) {
// 非-1则入栈
stack.push(num);
} else {
// -1则出栈:先判断栈是否空
if (!stack.isEmpty()) {
// 打印栈顶元素,再出栈
System.out.println(stack.getTop());
stack.pop();
} else {
// 栈空时输出错误提示并跳出循环
System.out.println("POP ERROR");
break;
}
}
}
// 销毁栈,释放资源
stack.destroy();
}
scanner.close();
}
}