我是Java初学者并尝试编写StackArray。我有一个测试人员来测试我的代码。我已经运行了好几次但它没有通过我的推送方法和我的搜索方法。谁能让我知道我做错了什么?非常感谢你!
import java.util.Arrays;
import java.util.NoSuchElementException;
public class Stack<E> implements StackADT<E>{
private E a[];
private int head, size;
public Stack(){
}
/*Adds the specified element to the top of the stack.
Returns the item added.*/
public E push(E element){
if (a.length == size){
throw new IllegalStateException("Cannot add to full stack");
}
// Since the remainder of the stack is to the RIGHT of the stack,
// adding a new element pushes the head to the LEFT (+ wrap around)
//head = (head - 1 + a.length) % a.length;
return a[head++] = element;
// return element;
}
/*Removes and returns the element from the top of the stack*/
public E pop(){
if (empty()){
throw new java.util.EmptyStackException();
}
// We need to get a copy of the old head before we advance to the
// new head. We want to return the old head, not the new head.
E rval = a[head];
// Why DON'T we need to add a.length here like we did in push?
head = (head + 1) % a.length;
return rval;
}
/*Returns without removing the element at the top of the stack*/
public E peek(){
if (empty()){
throw new java.util.EmptyStackException();
}
return a[head];
}
/*Returns true if the stack is empty, false otherwise*/
public boolean empty(){
return size == 0;
}
/*Returns the 1-based position where an object is on this stack
This means If the object o occurs as an item in this stack, this
method returns the distance FROM THE TOP OF THE STACK of the
occurrence nearest the top of the stack - the topmost item on
the stack is considered to be at distance 1.*/
public int search(Object o){
// i is the LOGICAL index
for (int i = 0; i < size; i++){
// p is the PHYSICAL index
int p = (head + i) % a.length;
E e = a[p];
// e == o Are the items (null or non-null the same?)
// if they are not the same, then at least one of them
// is non-null and can be compared to the other.
if (e == o || e != null && e.equals(o)){
// Distance = logical index + 1 as per the above description
return i + 1;
}
}
// No match was made
throw new NoSuchElementException();
}
/*Returns a string representation of the queue*/
public String toString(){
// Output should look like: [e_0, e_1, ..., e_n-1]
// Empty stack: []
if (empty())
return "[]";
// We know that there is at least one element in this stack
// since we didn't return
StringBuilder b = new StringBuilder();
b.append("[").append(a[head]);
// Start on the SECOND logical index
for (int i = 1; i < size; i++){
int p = (head + i) % a.length;
E e = a[p];
b.append(", ").append(e);
}
b.append("]");
return b.toString();
}
}
答案 0 :(得分:0)
最突出的错误是您没有实例化Stack
的实例变量。 Java对非初始化值使用默认值:原始数字设置为0
,布尔值设置为false
,所有引用类型(即数组和对象)设置为null
。这意味着head
和size
初始化为0
,而a
初始化为null
。后者在解除引用其内容时会产生NullPointerException
。
假设您想将数组作为内部表示,则必须以某种方式初始化E[]
的实例。不幸的是,你不能打电话给new E[size]
。有关如何实例化通用数组的信息,请参见 this other question 。
至于head
的初始值,它似乎应该指向堆栈的顶部,你在如何使用它时并不一致:在push
中,你使用head
作为a
中下一个自由元素的索引,并在添加元素后递增其值。在toString
,peek
和pop
中,您使用head
作为要返回的元素的索引。表示没问题,但你不能混淆它们。
假设您希望head
始终指向最后一个元素,您需要将其初始化为-1
并在push
- 方法中增加其值,然后才能访问{{1}中的索引}}。请注意a
和head++
:
++head
相当于
int i = head++;
而
int i = head;
head = head + 1;
相当于
int i = ++head;
以便修复,您可以更改
head = head + 1;
int i = head;
到
return a[head++] = element;
但最好添加几行代码,并通过首先递增return a[++head] = element;
的值来使逻辑更明确。
既然我们已经介绍了初始化,那么还有一个关于head
的值的错误:size
应该增加堆栈的大小,而push
应该递减它:但是,在你的代码中,pop
永远不会被修改,因此size
始终为真。
另外,我不太明白该行背后的想法
empty
// Why DON'T we need to add a.length here like we did in push?
head = (head + 1) % a.length;
中的。当一个元素被删除(而不是添加)时,如果你更喜欢postfix-operators,我会说这应该只是pop
或head = head - 1
。
正确初始化堆栈,例如
head--
更新private E a[];
private int head = -1;
private int size = 0;
public Stack(Class<E> c, int maxSize){
@SuppressWarnings("unchecked")
final E[] a = (E[]) Array.newInstance(c, maxSize);
this.a = a;
}
中size
的值,并将更新修正为push
:
head
更新public E push(E element){
if (a.length == size){
throw new IllegalStateException("Cannot add to full stack");
}
size++;
return a[++head] = element;
}
中的size
和head
的值:
pop
备注:我忽略了这些评论,因为评论往往会在代码被重构时出现;但我刚注意到你在评论中写道:
public E pop(){
if (empty()){
throw new java.util.EmptyStackException();
}
size--;
return a[head--];
}
实际上与代码中的下一行相反:// Since the remainder of the stack is to the RIGHT of the stack,
// adding a new element pushes the head to the LEFT (+ wrap around)
。建议的错误修正是基于代码而不是注释,因此堆栈的其余部分是return a[head++] = element;
的左边。因此,必须更改head
的实现,以便从右到左而不是从左到右打印数组:
toString