Scala函数用于获取大小为k的所有已排序子集

时间:2011-11-15 13:29:54

标签: function scala permutation sorted

我得到一组大小为L并且想要生成大小为k的每个已排序子集。 如果您的解决方案是scala,那可能会很棒,但也许我可以自己翻译。

L = 6且k = 3的示例运行应该产生。

1,2,3 1,2,4 1,2,5 1,2,6 1,3,4 1,3,5 1,3,6 1,4,5 1,4,6 1,5,6 2,3,4 2,3,5 2,3,6 2,4,5 2,4,6 2,5,6 3,4,5 3,4,6 3,5,6 4,5,6

我的scala尝试类似于:

object Util {
  def main(args : Array[String]) : Unit = {
    starts(6,3,1)
  }

  def starts(L: Int, num: Int, level: Int) : List[List[Int]] = {
    if( num == 0 ) {
      return List()
    }else{
      (level to (L-num+1)).map( o => o :: starts(L,num-1,level+1))
    }
  }
}

我希望你能帮助我。

3 个答案:

答案 0 :(得分:14)

你需要的只是

def subsets(L: Int, k: Int) =  
  1 to L combinations k

结果:

scala> subsets(6, 3) foreach println
Vector(1, 2, 3)
Vector(1, 2, 4)
Vector(1, 2, 5)
Vector(1, 2, 6)
Vector(1, 3, 4)
Vector(1, 3, 5)
Vector(1, 3, 6)
Vector(1, 4, 5)
Vector(1, 4, 6)
Vector(1, 5, 6)
Vector(2, 3, 4)
Vector(2, 3, 5)
Vector(2, 3, 6)
Vector(2, 4, 5)
Vector(2, 4, 6)
Vector(2, 5, 6)
Vector(3, 4, 5)
Vector(3, 4, 6)
Vector(3, 5, 6)
Vector(4, 5, 6)

根据需要。

答案 1 :(得分:1)

你可以从那个

开始
def subsets(start: Int, end: Int, count: Int) :Seq[Seq[Int]] = (
  if (count == 0) 
    List(Nil)
  else 
    for(head <- start to end; tail <- subsets(head + 1, end, count -1)) 
    yield head +: tail
)

答案 2 :(得分:1)

如果你实际上有而不是条目,那么你需要知道每个块有多长。你所展示的是条目(或者,相当于长度为1的块)。

首先,请注意我们必须L>=k。其次,请注意,如果第一个条目为i,则剩余的可能性为i+f(L-i,k-1),其中f是产生条目的内容,并假设+分布在集合中。最后,我们注意到flatMap具有为每个元素生成序列的函数,将结果解压缩为单个序列。

现在我们已经掌握了所有需要知道的内容:

def choices(N: Int, k: Int): List[List[Int]] = {
  if (k==1) (1 to N).toList.map(x => List(x))
  else if (N < k) Nil
  else (1 to 1+N-k).toList.flatMap{ i =>
    choices(N-i,k-1).map(xs => i :: xs.map(_ + i))
  }
}

如果你确实意味着块,那么我们需要知道块有多长。分析是相同的,除了不跳过一个值,我们需要跳过块大小:

def blockchoices(N: Int, k: Int, size: Int): List[List[Int]] = {
  if (k==1) (1 to N+1-size).toList.map(x => List(x))
  else if (N <= k+size) Nil
  else (1 to 2+N-k-size).toList.flatMap{ i =>
    choices(N-i+1-size, k-1, size).map(xs => i :: xs.map(_ + i+size-1))
  }
}

(列出了该块的起始条目)。