【数据结构】栈算法题

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函数定义如下:

123456.png

写出计算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函数定义如下:

123456.png

写出计算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();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值