我正在学习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
}
}
}
但很遗憾,此代码返回空Set。我怀疑这个问题是由于Immutable集合使用而发生的。我试图在Debugger中运行它,我看到函数的递归调用总是返回空集,我的代码永远不会进入foreach函数。
请帮忙。欢迎任何想法。
答案 0 :(得分:4)
在惯用scala中,应用于不可变集合的+
(和-
,++
等)运算符会创建一个新集合 - 否则它们将不会是不可变的。相反,您必须将修改与another piece of syntactic sugar结合使用,如果您将=
附加到运算符,它会将运算符的结果分配给左侧变量:superSet += f + newSet
。
答案 1 :(得分:0)
我用这种方式解决了问题:
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))
但我很高兴知道是否有更优雅的解决方案