如何解决回文检查抛出无限循环使用迭代器和链表集合
我正在尝试编写一种方法来确定字符串类型的单向链表是否为回文。
想法是将后半部分复制到堆栈中,然后使用迭代器弹出堆栈中的元素并检查它们是否与从 0 到单向链表的一半左右的元素相同。
public static boolean ispalindrome(LinkedList<String> list,Stack<String> stack ) {
int halfList = (int) Math.ceil(list.size()/2); // we get half the list size,then round up in case it´s odd
// testing: System.out.println("half of size is " + halfList);`
// copy elements of sll into the stack (push them in) after reaching the midpoint
int count = 0;
boolean isIt = true;
Iterator<String> itr = list.iterator();
Iterator<String> itr2 = list.iterator();
System.out.println("\n i print too! ");
// CHECK!! Node head = list.element();
// LOOP: traverse through sll and add the second half to the stack (push)
// if even # of elements
if ( list.size() % 1 == 0 ) {
System.out.println("\n me too! ");
while ( itr.hasNext() ) {
String currentString = itr.next(); // this throws an exception in thread empty stack exception
count ++;
if ( count == halfList ) stack.push(list.element());
// THIS IS THE INFINITE LOOP
System.out.println("\n me three! ");
}
}
// else,if odd # of elements
else {
while ( itr.hasNext() ) {
count ++;
if ( count == halfList -1 ) stack.push(list.element());
}
}
// Now we compare the first half of the sll to the stack (pop off elements)
// even
if ( list.size() % 1 == 0 ) {
while ( itr2.hasNext() ) {
count ++;
if ( count == halfList +1 ) break;
int compared = stack.pop().compareto(list.element());
if ( compared != 0) isIt = false; // if when comparing the two elements,they aren´t similar,palindrome is false
}
}
// odd
else {
while ( itr2.hasNext() ) {
count ++;
if ( count == halfList ) break;
int compared = stack.pop().compareto(list.element());
if ( compared != 0) isIt = false;
}
}
return isIt;
}
我做错了什么?
解决方法
有很多问题:
-
list.size() % 1 == 0
不检查大小是否偶数。正确的检查是% 2
。 - 堆栈异常不能出现在您放置该注释的行上。它发生在您拥有
stack.pop()
的代码下方。出现此异常的原因是您尝试从没有更多元素的堆栈中弹出一个元素。 - 在您放置该评论的地方不会发生无限循环。它会发生在您在代码中的任何其他循环中:在那里您永远不会调用
itr.next()
或itr2.next()
,因此您将无限循环到达那里。 - 堆栈永远不会被压入超过 1 个值。这是因为您有一个严格的相等条件,该条件在迭代期间只为真一次。这不是您想要的:您希望列表的一半最终出现在堆栈中。这也是您收到堆栈错误的原因:您的代码的后半部分期望堆栈上有足够的项目。
-
push(list.element())
总是将 第一个 列表值推入堆栈,而不是当前迭代的值。这应该是push(currentString)
。 -
count ++;
被放置在循环中一个不直观的地方。如果将该行移动为循环中的最后一条语句,则更有意义。 -
if ( count
语句都是错误的。如果您将count ++
移至最后一个语句,则此if
应为偶数情况为if ( count >= halfList )
,而为奇数情况为if ( count > halfList )
。当然,如果调整halfList
会更容易,这样您就可以平等地处理奇数和偶数情况。 - 您的代码的第二部分没有重置计数器,而是继续使用
count ++
。这将使if ( count == halfList )
永远不会为真,因此这也是stack.pop()
最终会引发异常的另一个原因。要么您应该在开始第二部分之前重置计数器(使用count = 0;
),或者更好的是,您应该检查堆栈是否为空,然后退出循环。 - 您的代码的后半部分不需要区分奇数或偶数。
- 与其将
isIt
设置为 false,不如立即使用return false
退出 函数,因为继续迭代没有进一步的好处。立> - 该函数不应将堆栈作为参数:您总是希望从一个空堆栈开始,因此这应该是一个局部变量,而不是一个参数。
- 对已经是
Math.ceil
的结果执行int
是没有用的。当两个参数都是int
时,除法会产生int
。所以要向上舍入,在除法之前加 1:(list.size()+1) / 2
- 避免代码重复
当您调试代码时,这些问题中的大多数都很明显。将打印行与“我在这里”放在一起并没有太大帮助。更好的是打印变量的值,或者在检查变量的同时使用良好的调试器单步调试代码。如果您这样做了,您就会发现上面列出的许多问题。
以下是已解决上述问题的代码版本:
public static boolean isPalindrome(LinkedList<String> list) {
Stack<String> stack = new Stack<String>();
int halfList = (list.size()+1) / 2; // round upwards
Iterator<String> itr = list.iterator();
while (halfList-- > 0) itr.next(); // skip first half of list
while ( itr.hasNext() ) stack.push(itr.next()); // flush rest unto stack
Iterator<String> itr2 = list.iterator();
while ( itr2.hasNext() && !stack.empty()) { // check that stack is not empty
if (stack.pop().compareTo(itr2.next()) != 0) return false; // no need to continue
}
return true;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。