【问题标题】:How to achieve pass-by-reference in recursive methods in Java如何在Java中的递归方法中实现引用传递
【发布时间】:2014-11-23 10:51:11
【问题描述】:

在 Java 中我们可以通过哪些方式实现/模拟通过引用传递? 为了检查链表是否是回文,我编写了以下代码。有用/ 但我想知道是否有任何其他方法可以在不使用包装类的情况下实现这一目标。

   class MyClass {
        ListNode mover = head;
        boolean b = true;
    }

public boolean checkPalindrome(){

        ListNode temp = head;

        int len = length()/2 + length()%2;

        MyClass myObj = new MyClass();

        int i =(len%2 == 1) ? len:len-1;

        while(i>1){
            myObj.mover = myObj.mover.next;
            i--;
        }
        boolean e = checkPalindrome(temp, myObj, len);
        return e;
    }

    public boolean checkPalindrome(ListNode head, MyClass ref, int len) {

        if(head == null || len == 0)
            return true;

        len = len-1;

        checkPalindrome(head.next,ref, len);
        ref.mover = ref.mover.next;
        ref.b = ref.b && (head.value==ref.mover.value);
        return ref.b;
    }

为了获得“ref”对象的当前位置,我编写了 MyClass 包装器。还有比这更好的方法吗?

【问题讨论】:

  • 这看起来根本不会检查回文 - 看起来它可能会检查列表的前半部分是否等于列表的后半部分。但是,在我看来,您根本不需要额外的课程 - 您只需要传递ListNode,并使用递归调用的返回值(您目前忽略)。您提供的代码甚至无法编译也无济于事 - 您正在使用一个名为 iterator 的变量,该变量不存在。
  • 我修改了迭代器部分。
  • 它还检查回文,这就是使用递归的原因,当递归遇到基本情况时,移动器向前移动,而头向后滚动,我比较它们。
  • 另外,如果我改变了返回类型,那我就不能再返回布尔值了吧?
  • 你在哪里“向后滚动”?您正在使用ref.mover.nexthead.next?或者是您在递归步骤中将头部迭代器向前移动到最后,并且稍后仅将ref 向前移动一个?与在开始时使用一个迭代器并在末尾使用一个迭代器相比,它非常 令人困惑。我从不建议更改返回类型 - 我建议 使用 返回值。然而,既然我认为我理解了你有效地倒退的复杂方式,那可能无济于事。这只是一个单链表吗?

标签: java recursion linked-list pass-by-reference inner-classes


【解决方案1】:

在 Java 中执行此类操作的一个经典技巧是传递一个元素的数组参数。数组本身是通过引用传递的,函数可以操作第一个元素。像这样的:

myMethod(int arr[], int anotherArg) {
   arr[0] = 123;
}

// Use like this:
int myArr[] = {321}
myMethod(arr, 0)
// myMethod() has "returned" something in arr's 1st element. 

【讨论】:

    【解决方案2】:

    您只需要额外的类,因为您有 两条 条信息需要维护 - 而您只有两条信息需要维护,因为您忽略了递归调用。我怀疑您可以将代码更改为使用AtomicReference

    public boolean checkPalindrome(ListNode head,
                                   AtomicReference<ListNode> tailRef,
                                   int len) {
        if (head == null || len == 0) {
            return true;
        }
    
        len--;
    
        boolean ret = checkPalindrome(head.next, tailRef, len);
        ListNode tail = tailRef.get().next;        
        tailRef.set(tail);
        return ret && head.value == tail.value;
    }
    

    我没有彻底检查过,但如果不是相当,你应该可以很容易地修复它。

    【讨论】:

      【解决方案3】:

      下面的示例代码:

      static LinkedList<String> list = new LinkedList<String>();
      
      public static void main(String[] args) {
          list.add("A");
          list.add("B");
          list.add("C");
          list.add("A");
          boolean result = CheckPalindrome(list.subList(0, list.size()));
          System.out.println("List " + list + "is Palindrome?");
          System.out.println(result);
      }
      
      public static boolean CheckPalindrome(List<String> linkedL) {
          if (linkedL.size() <= 1)
              return true;
          if (linkedL.get(0).equals(linkedL.get(linkedL.size() - 1))) {
              return CheckPalindrome(linkedL.subList(1, linkedL.size() - 1));
          } else {
              return false;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        • 2017-04-23
        • 1970-01-01
        相关资源
        最近更新 更多