我必须为链表类编写一个非常简单的方法,但我遇到了一些问题。这个名为squish()
的方法采用此列表,并且在两个或更多连续项目的位置
相等(使用equals()
进行比较),它会删除重复的节点,以便只保留一个连续的副本。因此,在完成程序后,此列表中没有两个连续项目相同。
执行squish()
后,列表可能会比squish()
开始时短。没有额外的项目可以弥补被删除的内容。
例如,如果输入列表为[ 0 0 0 0 1 1 0 0 0 3 3 3 1 1 0 ]
,则输出列表为[ 0 1 0 3 1 0 ]
。
这是我的方法:
public void squish() {
SListNode current = head;
boolean end =false;
while(end == false )
{
if(!current.item.equals(current.next.item))
current=current.next;
else
{
while(current.item.equals(current.next.item) && current.next !=null)
current.next=current.next.next;
current=current.next;
}
if (current==null)
end=true;
}
}
这是执行代码的一个小主要部分。
public class main {
public static void main(String args[])
{
int[] test6 = {6, 6, 6, 6, 6, 3, 6, 3, 6, 3, 3, 3, 3, 3, 3};
SList list6 = new SList();
for (int i = 0; i < test6.length; i++) {
list6.insertEnd(new Integer(test6[i]));
}
System.out.println("squishing " + list6.toString() + ":");
list6.squish();
String result = list6.toString();
System.out.println(result);
int[] test5 = {3, 7, 7, 7, 4, 5, 5, 2, 0, 8, 8, 8, 8, 5};
SList list5 = new SList();
for (int i = 0; i < test5.length; i++) {
list5.insertEnd(new Integer(test5[i]));
}
System.out.println("squishing " + list5.toString() + ":");
list5.squish();
result = list5.toString();
System.out.println(result);
}
}
调试代码我可以看到该方法工作正常..只在列表的末尾,他转发了一个空异常指针。你能帮助我吗?感谢
答案 0 :(得分:4)
我会这样做:
public void squish() {
SListNode current = head; //1
if(current = null) return; //1a
while(current.next != null) { //2
if(current.item.equals(currennt.next.item))
current.next = current.next.next; //3
else
current = current.next; //4
}
}
这是教授为递归分配的东西,虽然大多数专业人员不使用递归,但我已经设置了这种方法。
第1行是init,您将遍历列表的指针指向链接列表的开头。
第1a行如果列表中没有元素,那么我们返回。
第2行是基本情况。如果我们在列表中只有一个元素,那么无所事事。
第3行是归纳,如果我们指向一个节点,我们检查隔壁的节点。如果它们具有相等的值,那么我们可以删除隔壁的节点。
第4行是第3行的else,我们查看了隔壁的节点,发现它不相等。因此,我们遍历清单。
手动遍历问题中提供的测试数据可能是一项有用的练习,然后在我的示例中添加一些System.out.println以查看您是否正确。我今天必须用一些棘手的代码来解决发生了什么。
答案 1 :(得分:4)
问题出在这一行:
while(current.item.equals(current.next.item) && current.next !=null)
这里,条件的第一部分访问current.next.item
,即使current.next
为空,因为条件的第二部分(current.next !=null
)在>后检查 em>第一个(仅当第一个评估为true
时,见下文)。要修复它,只需反转条件:
while(current.next !=null && current.item.equals(current.next.item))
这样,表达式current.item.equals(current.next.item)
只会在current.next !=null
为真(short-circuit evaluation)时执行,即在安全的情况下执行。
另外,我认为你可以放弃第一个if
声明。看看@ Pete关于如何简化方法的答案。
答案 2 :(得分:2)
当在最后一次迭代中执行第if(!current.item.equals(current.next.item))
行时,current.next
指向null
,因为current
是列表中的最后一项,实际上没有下一个项目。
修改强>
现在,在您的评论中,我看到您获得了行中的NullPointerException
while(current.item.equals(current.next.item) && current.next !=null)
好吧,你应该只是将这两个条件相互替换:首先验证current.next
不是null
,然后才等同于current
和next
:
while(current.next !=null && current.item.equals(current.next.item))
顺便说一句,当你的列表只有一个元素时,你仍然会在行if(!current.item.equals(current.next.item))
中得到NPE。例如,要修复此问题,只需检查是否head.next == null
。如果是这样,请不要首先启动while
循环。