【问题标题】:Problems in recursively generating subset递归生成子集的问题
【发布时间】:2019-03-08 04:58:58
【问题描述】:

因此,该算法通过使用参数 i 来引用 A[i] 来生成集合 A 的子集,在每个步骤中,有两个调用,一个包括 A[i],另一个不包括 A[i]。 当 i==n 时搜索停止。

所以,这是有道理的,但我不明白最后一个语句在这里做了什么..

void search(int i, ArrayList<Integer> subset,ArrayList<Integer> A, int n){
        if (i==n) System.out.println(subset);
        else{
            search(i+1,subset,A,n);
            subset.add(A.get(i));
            search(i+1,subset,A,n);
            subset.remove(subset.size()-1); /*Why do we need to do this? I am not making any function call after this*/
        }
}

我尝试排除最后一条语句,但它会重复子集中的元素。最后一条语句有什么用?

【问题讨论】:

  • 您是否尝试使用回溯生成子集?
  • @uneq95 是的,我知道这不是最有效的方法。
  • @MBo 为您提供正确答案

标签: java algorithm subset


【解决方案1】:

您拥有在所有递归级别共享的唯一 subset 实例。

所以在使用项目后你应该回到较低的级别,与subset相同的状态。

想象一下调用树

[]
     []
     [2]  *

[1]  
     [1]
     [1 2]

创建子集[2](代码点*)后,返回第一级,必须生成子集[1]。但是subset对象已经包含第2项,所以如果不删除*中的第2项,[1]的生成是不可能的


如果实现创建参数的新副本,则不需要恢复状态。

【讨论】:

  • 对不起,没听懂,我的意思是最初的子集=[],当我第一次调用搜索时,我正在共享[],然后是子集=[A[0]],然后我正在使用这个实例又名 [ A[0] ],为什么我需要删除 A[0] 并再次设置子集 = [ ]?之后我没有进行任何函数调用,我在哪里共享该实例?
  • ArrayList&lt;Integer&gt; subset 参数实际上是对象的地址。只有一个对象副本确实存在(如果您不进行深层复制)。当您在更深的递归级别修改对象时,也会在更高级别看到更改。我添加了示例。
  • @Little_idiot 你知道将答案标记为解决方案吗?
猜你喜欢
  • 2020-09-17
  • 1970-01-01
  • 2019-04-22
  • 2012-01-27
  • 2016-03-14
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多