创建所有子集

时间:2017-02-21 22:00:37

标签: scala set subset

确定。我知道。这是奥德斯基课程的练习。但是我好好坚持了好几天。

定义创建输入集的所有子集的方法:

def combination(occ: List[(Char,Int)]) : List[List[(Char,Int)]]

示例:输入List(('a', 2), ('b', 2))获取输出:

List(
  List(),
  List(('a', 1)),
  List(('a', 2)),
  List(('b', 1)),
  List(('a', 1), ('b', 1)),
  List(('a', 2), ('b', 1)),
  List(('b', 2)),
  List(('a', 1), ('b', 2)),
  List(('a', 2), ('b', 2))
)

完美。目前我得到了两个不同的东西:所有夫妻(1a)和单一元素(1b)的列表

1a 它有效。它给了我所有的夫妻(一般的元组)

  def combinations(occurrences: List[(Char,Int)]) : List[List[(Char,Int)]] = {
    if (occurrences.isEmpty) List(Nil)
    else {
      val entry = occurrences.head;
      for (
           first <- (entry._2 to 1 by -1).toList;
           rest <- combinations(occurrences.tail))
        yield (entry._1, first) :: rest
    }
  }

输出List(List((a,2), (b,2)), List((a,2), (b,1)), List((a,1), (b,2)), List((a,1), (b,1)))

图1b 即可。它工作,除了我没有得到空列表(当然,我没有)

  def combinations(occurrences: List[(Char,Int)]) : List[List[(Char,Int)]] = {
    for (entry <- occurrences;
         freq <- (entry._2 to 1 by -1).toList) yield List((entry._1,freq))

  }

输出List(List((a,2)), List((a,1)), List((b,2)), List((b,1)))

现在我完全陷入困境如何将两者结合起来。 你能帮我理解我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:0)

不确定效率,但你可以看看这个。这是一种硬币更换问题,即,考虑到总金额和所有可能的硬币,有多少种方式可以组成这种变化。其中一个想法(从上到下的方法)是想出一个递归函数,它分叉你是否会采用特定种类的硬币,这就是内部组合函数在这里做的事情: / p>

def combinations(occurrences: List[(Char,Int)]) : List[List[(Char,Int)]] = {
    // total number of coins
    val tot = occurrences.map(_._2).sum

    // add a pair to an existing combination
    def add(counter: List[(Char, Int)], element: (Char, Int)) = {
      val countMap = counter.toMap
      (countMap + (element._1 -> (countMap.getOrElse(element._1, 0) + element._2))).toList
    }

    // a recursive function to calculate all the combinations
    def combinations(occurs: List[(Char,Int)], n: Int): List[List[(Char,Int)]] = {
      if(n == 0) List(List())
      else if(occurs.isEmpty) List()
      else {
        val firstElement = if(occurs.head._2 == 1) List() else List((occurs.head._1, 1))
        // all the combinations if you take the first kind of coin
        val headComb = combinations(firstElement ++ occurs.tail, n - 1)

        // all the combinations if you don't take the first kind of coin
        val tailComb = combinations(occurs.tail, n)    

        // add the first coin pair to head combination and concatenate it with tail combination
        headComb.map(add(_, (occurs.head._1, 1))) ++ tailComb    
      }
    }

    // calculate the combinations for each amount separately
    (0 to tot).toList.flatMap(combinations(occurrences, _))
}


combinations(List())
// res49: List[List[(Char, Int)]] = List(List())

combinations(List(('a', 1)))
// res50: List[List[(Char, Int)]] = List(List(), List((a,1)))


combinations(List(('a', 1), ('b', 2)))
// res51: List[List[(Char, Int)]] = List(List(), List((a,1)), List((b,1)), List((b,1), (a,1)), List((b,2)), List((
// b,2), (a,1)))

combinations(List(('a', 2), ('b', 2)))
// res52: List[List[(Char, Int)]] = List(List(), List((a,1)), List((b,1)), List((a,2)), List((b,1), (a,1)), List((
// b,2)), List((b,1), (a,2)), List((b,2), (a,1)), List((b,2), (a,2)))

答案 1 :(得分:0)

我可以给你一个提示,但是我不能给你一个解决方案,因为会违反荣誉代码

请注意,在您的推理中,将(_, 0)视为空集并且所有集都包含空集是一件好事!你可以想出一个过滤掉它们的解决方案。

List(('a', 2), ('b', 2)) <=> List(('a', 2), ('b', 2), ('a', 0), ('b', 0))

我希望它会对你有所帮助!祝你好运!