【问题标题】:Scala Code - Immutable Set IssuesScala 代码 - 不可变集问题
【发布时间】:2013-09-09 23:11:32
【问题描述】:

我正在学习 Scala,我想将一些旧算法代码转换为 Scala。

我有非常简单的 Java 代码,可以打印 superSet(所有可能的集合的组合,包括空集合和集合本身)。

public static Set<Set<Integer>> createSuperSet(Set<Integer> originalSet){
    Set<Set<Integer>> superSet = new HashSet<Set<Integer>>();

    if (originalSet.size() == 0){
        Set<Integer> empty = new HashSet<Integer>();
        superSet.add(empty);
        return superSet;
    }

    List<Integer> list = new ArrayList<Integer>(originalSet);
    Integer head = list.get(0);
    Set<Integer> rest = new HashSet<Integer>(list.subList(1, list.size()));
    for (Set<Integer> set  : createSuperSet(rest)){
        Set<Integer> newSet = new HashSet<Integer>();
        newSet.add(head);
        newSet.addAll(set);
        superSet.add(newSet);
        superSet.add(set);
    }       
    return superSet;
}

现在我正在尝试在 Scala 中实现相同的功能:

  def createSuperSet(originalSet: Set[Int]): Set[Set[Int]] ={
     val superSet = Set[Set[Int]]()

     originalSet.toList match {   

       case List() => {superSet + Set[Int]()} 

       case head::restAsList => {
         val rest = restAsList.toSet[Int]
         val result = createSuperSet(rest)
         result.foreach(f=>{
           val newSet:Set[Int] =  f + head
           superSet + f +newSet
         }) 
         superSet
       }
     }   
  }

但不幸的是,此代码返回空集。我怀疑这个问题是由于不可变集合的使用而发生的。我试图在调试器中运行它,我看到对函数的递归调用总是返回空集,我的代码永远不会进入 foreach 函数。

请帮忙。欢迎任何想法。

【问题讨论】:

    标签: algorithm scala functional-programming


    【解决方案1】:

    在惯用的 scala 中,应用于不可变集合的 +(和 -++ 等)运算符会创建一个新集合 - 否则它们将不是不可变的。相反,您必须将修改与another piece of syntactic sugar 结合起来,如果您将= 附加到运算符,它会将运算符的结果分配给左侧变量:superSet += f + newSet

    【讨论】:

    • superSet += f + newSet 表达式无法编译。
    • 您已将其声明为 val,因此无法重新分配 superSet
    【解决方案2】:

    我是这样解决问题的:

     def createSuperSet(originalSet: Set[Int]): Set[Set[Int]] ={
         var superSet = Set[Set[Int]]()
    
         originalSet.toList match {   
    
           case List() => {superSet + Set[Int]()} 
    
           case head::restAsList => {
             val rest = restAsList.toSet[Int]
             val result = createSuperSet(rest)
             result.map(f=>{
               superSet = superSet  + f+ (f+head)
             }) 
             superSet
           }
         }   
      }
    

    运行println(createSuperSet(Set[Int](1,2,3))

    打印

    Set(Set(), Set(3, 1), Set(2), Set(2, 1), Set(3, 2), Set(3), Set(3, 2, 1), Set(1))
    

    但我很高兴知道是否有更优雅的解决方案

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 2011-11-24
      • 2012-01-07
      • 2011-02-17
      • 2013-08-30
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多