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方法说明
- 输入n,建立可包含n个元素的ArrayIntegerStack对象
- 输入m个值,均入栈。每次入栈均打印入栈返回结果。
- 输出栈顶元素,输出是否为空,输出size
- 使用Arrays.toString()输出内部数组中的值。
- 输入x,然后出栈x次,每次出栈均打印。
- 输出栈顶元素,输出是否为空,输出size
- 使用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 的每个节点除了存储元素值外,还需要额外存储前驱和后继节点的指针,这使得其内存开销相对较大。尤其是在存储大量小数据时,指针所占用的内存比例会更加明显。

浙公网安备 33010602011771号