2017-08-16 40 views
1

我想在Java中进行递归,传递对象参数。事情是这样的:现在在递归中传递对象参数有效吗?

int recursion(Object object) 
{ 
    //do a little bit modification to the object 
    int i1= recursion(modified_object_1); 
    //do a little bit modification to the object 
    int i2= recursion(modified_object_2); 
    //do a little bit modification to the object 
    int i3= recursion(modified_object_3); 
    return max(i1, i2, i3); 
} 

,因为对象是通过引用传递,我要克隆的对象参数的3倍和克隆的对象传递给下一个递归。但是,这可能是非常低效的,因为我正在进行数万次递归,而且对象结构复杂。除了克隆对象之外,还有更有效的方法吗?

谢谢〜

+0

如果您需要*数万次递归*,请在对象定义中设置递归循环。或者详细说明你想要实现什么以及对象**的一些修改是什么 – nullpointer

+0

你可能想要考虑废弃动态编程迭代方法的递归方法,类似于人们经常使用的经典的斐波那契程序介绍类 –

+0

只是一个修正,你通过** value **传递对象,通过**引用**传递对象(也就是将它传递给内存中的地址)是最有效的方法。尽管如此,它不可能在Java –

回答

3

首先关于通过价值和参考(OP看起来很清楚,但评论者似乎困惑)有点清晰。 Java对象在传递给函数时不会自动克隆 - 对象的引用是按值传递的 - 在函数中更改对象将更改调用上下文中的对象。

因此,OP正确计划运行他的算法,他需要首先克隆对象,然后使用克隆副本向下传递递归函数链。

然而有一个其他的可以在某些情况下可以轻松实现可能性:

int recursion(Object object) 
{ 
    //do a little bit modification to the object 
    int i1= recursion(object); 
    //undo the modification to the object 
    //do a little bit modification to the object 
    int i2= recursion(object); 
    //undo the modification to the object 
    //do a little bit modification to the object 
    int i3= recursion(object); 
    //undo the modification to the object 
    return max(i1, i2, i3); 
} 

在情况下,这是可能的(例如搜索游戏决策树时选择一个可能的移动时),它可以更有效率的。

请注意,上次撤销更改需要否则堆栈中较高的对象将出错。

1

我不认为你能避免复制这些对象

我的建议是建立一个预功能,从你为了建立一些需要这些对象的一切提取一种“尽可能小的对象”,以便在递归中尽可能复制尽可能少的字段。

最好的情况是,如果你可以提取原始类型,并使用它们进行递归。无论如何,更具体的帮助你应该发布更多的细节(例如你的对象/修改)

-1

在java中,你不能通过引用传递参数,只是通过值。在你的情况下,可能的解决方法是将对象定义为方法所在类的属性。例如:

class RecursionClass { 
    private Object object; 

    public void setObject(Object object) { 
     this.object = object; 
    } 

    int recursion() { 
     if(object == null) 
      throw new Exception("Set the object first!"); 

     // define modified objects base on object 


     //do a little bit modification to the object 
     int i1= recursion(modified_object_1); 
     //do a little bit modification to the object 
     int i2= recursion(modified_object_2); 
     //do a little bit modification to the object 
     int i3= recursion(modified_object_3); 
     return max(i1, i2, i3); 
    } 
} 
3

考虑使用不可变对象。递归算法在堆栈共享正在被修改的对象时变得特别难以考虑。

装饰模式可以帮助提高效率和内存使用率。例如,如果你改变一个字段:

class UserWithAgeChanged implements User { 

     private User delegate; 
     private int age; 

     public UserWithAgeChanged(User user, int newAge) { 
      this.delegate = user; 
      this.age = newAge; 
     } 

     @Override 
     public String getName() { 
      return delegate.getName(); 
     } 

     // similar methods for all delegated fields 

     @Override 
     public String getAge() { 
      return age; 
     } 
} 

(有库,帮助你做这种事情 - 比如Immutables library

现在你可以做一些类似的递归:

// silly functionality, but you get the point 
    void recurse(User user) { 
     if(user.getAge() == 44) { 
      return user; 
     } else { 
      recurse(new UserWithAgeChanged(user, user.getAge() + 1); 
     } 
    } 

这将创建一个代表链,大多数是微小的对象,最后有更大的“根”User对象。在一个更复杂的算法中,最终会得到一个不可变对象的网络,但不会有太多的复制或克隆正在进行 - 而是会有很多委托。