jmu-Java-PTA题解 (5.3 面向对象进阶-自定义接口ArrayIntegerStack) 网安2312陈卓

问题要求

定义IntegerStack接口,用于声明一个存放Integer元素的栈的常见方法:

public Integer push(Integer item);
//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。

public Integer pop();   //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
public Integer peek();  //获得栈顶元素,如果为空,则返回null.
public boolean empty(); //如果为空返回true
public int size();      //返回栈中元素个数

定义IntegerStack的实现类ArrayIntegerStack,内部使用数组实现。创建时,可指定内部数组大小。

main方法说明

  1. 输入n,建立可包含n个元素的ArrayIntegerStack对象
  2. 输入m个值,均入栈。每次入栈均打印入栈返回结果。
  3. 输出栈顶元素,输出是否为空,输出size
  4. 使用Arrays.toString()输出内部数组中的值。
  5. 输入x,然后出栈x次,每次出栈均打印。
  6. 输出栈顶元素,输出是否为空,输出size
  7. 使用Arrays.toString()输出内部数组中的值。

思考

如果IntegerStack接口的实现类内部使用ArrayList来存储元素,怎么实现?测试代码需要进行什么修改?

输入样例:

5
3
1 2 3
2

输出样例:

1
2
3
3,false,3
[1, 2, 3, null, null]
3
2
1,false,1
[1, 2, 3, null, null]

关键点

  • 接口设计:IntegerStack 接口明确了栈操作的基本方法,这使得栈的实现与使用分离,提高了代码的可维护性和可扩展性。其他类只要实现该接口,就能作为栈使用,符合面向接口编程的原则。
  • 泛型与类型安全:本题虽然处理的是 Integer 类型,但如果要扩展到其他类型,可使用泛型。使用泛型能在编译时检查类型,避免运行时的类型转换错误,增强代码的安全性。
  • 数组实现栈:ArrayIntegerStack 类使用数组存储栈元素,需要管理栈顶指针 index 来控制元素的进出栈。同时,要考虑栈满和栈空的情况,确保程序的健壮性。
  • 输入输出处理:在 main 方法中,需要根据用户输入的不同参数进行入栈、出栈操作,并按照要求输出栈的状态信息,这涉及到对用户输入的正确解析和结果的格式化输出。

解题步骤

第一步:定义 IntegerStack 接口

运用泛型思想,定义 IntegerStack 接口,确保接口方法能对 Integer 类型数据进行操作。

interface IntegerStack {
    public Integer push(Integer item);
    public Integer pop();
    public Integer peek();
    public boolean empty();
    public int size();
}

第二步:实现 IntegerStack 接口

创建 ArrayIntegerStack 类来实现 IntegerStack 接口,内部借助数组存储元素。

import java.util.Arrays;

class ArrayIntegerStack implements IntegerStack {
    Integer[] arr;
    int length;
    int index;

    public ArrayIntegerStack(int n) {
        arr = new Integer[n];
        for (int i = 0; i < n; i++) {
            arr[i] = null;
        }
        this.length = n;
        this.index = 0;
    }

    public Integer push(Integer item) {
        if (item == null) {
            return null;
        }
        if (index == length) {
            return null;
        }
        arr[index] = item;
        index = index + 1;
        return item;
    }

    public Integer pop() {
        if (index == 0) {
            return null;
        }
        index = index - 1;
        Integer e = arr[index];
        return e;
    }

    public Integer peek() {
        if (index == 0) {
            return null;
        }
        Integer e = arr[index - 1];
        return e;
    }

    public boolean empty() {
        if (index == 0) {
            return true;
        }
        return false;
    }

    public int size() {
        return index;
    }
}

第三步:实现 main 方法

在 main 方法里,依据用户输入开展栈操作,包含入栈、出栈,并且输出相应结果。

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        IntegerStack arrayIntegerStack = new ArrayIntegerStack(n);
        int m = in.nextInt();
        for (int i = 0; i < m; i++) {
            Integer e = in.nextInt();
            Integer x = arrayIntegerStack.push(e);
            System.out.println(x);
        }
        System.out.println(arrayIntegerStack.peek() + "," + arrayIntegerStack.empty() + "," + arrayIntegerStack.size());
        System.out.println(Arrays.toString(((ArrayIntegerStack) arrayIntegerStack).arr));
        int x = in.nextInt();
        for (int i = 0; i < x; i++) {
            Integer e = arrayIntegerStack.pop();
            System.out.println(e);
        }
        System.out.println(arrayIntegerStack.peek() + "," + arrayIntegerStack.empty() + "," + arrayIntegerStack.size());
        System.out.println(Arrays.toString(((ArrayIntegerStack) arrayIntegerStack).arr));
    }
}

整体流程图:

整体代码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;

class IntegerStack{
    Integer[] arr;
    int length;
    int index;

    public IntegerStack(int n){
        arr = new Integer[n];
        for(int i=0;i<n;i++){
            arr[i] = null;
        }
        this.length = n;
        this.index = 0;
    }

    public Integer push(Integer item){
        if(item == null){
            return null;
        }
        if(index == length){
            return null;
        }
        arr[index] = item;
        index = index + 1;
        return item;
    }

    public Integer pop(){
        if(index == 0){
            return null;
        }
        index = index - 1;
        Integer e = arr[index];
        return e;
    }
    
    public Integer peek(){
        if(index == 0){
            return null;
        }
        Integer e = arr[index-1];
        return e;
    }
    
    public boolean empty(){
        if(index == 0){
            return true;
        }else{
            return false;
        }
    }
    
    public int size(){
        return index;
    }

}

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        IntegerStack ArrayIntegerStack = new IntegerStack(n);
        int m = in.nextInt();
        for(int i=0;i<m;i++){
            Integer e = in.nextInt();
            Integer x = ArrayIntegerStack.push(e);
            System.out.println(x);
        }
        System.out.println(ArrayIntegerStack.peek()+","+ArrayIntegerStack.empty()+","+ArrayIntegerStack.size());
        System.out.println(Arrays.toString(ArrayIntegerStack.arr));
        int x = in.nextInt();
        for(int i=0;i<x;i++){
            Integer e = ArrayIntegerStack.pop();
            System.out.println(e);
        }
        System.out.println(ArrayIntegerStack.peek()+","+ArrayIntegerStack.empty()+","+ArrayIntegerStack.size());
        System.out.println(Arrays.toString(ArrayIntegerStack.arr));
    }
}

思考:ArrayList 为了实现动态扩容,会预留一定的内存冗余,在创建时,会分配一个初始容量的数组,当元素数量超过容量时,会创建一个更大的数组并复制元素。这种机制虽然提供了灵活性,但也会导致在某些情况下占用比实际需求更多的内存。题目中将 IntegerStack arrayIntegerStack = new ArrayIntegerStack(n); 修改为 IntegerStack arrayIntegerStack = new ArrayListIntegerStack(n); 即可实现ArrayList;同样也可以考虑使用LinkedList,LinkedList支持队列和双端队列的操作,如在队头或队尾添加、删除元素等,功能更为丰富和灵活,但LinkedList 的每个节点除了存储元素值外,还需要额外存储前驱和后继节点的指针,这使得其内存开销相对较大。尤其是在存储大量小数据时,指针所占用的内存比例会更加明显。

posted @ 2025-04-18 10:32  取名字比写博客还难  阅读(34)  评论(0)    收藏  举报