3

我刚开始使用 Scala,对于我的第一个项目,我正在编写一个数独求解器。我遇到了一个很棒的网站,它解释了数独以及如何编写求解器:http: //norvig.com/sudoku.html,我正在尝试从这个网站创建相应的 Scala 代码。

数独网格的正方形基本上是行名和列名的叉积,这可以在 Python 中使用列表推导非常容易地生成:

# cross("AB", "12") = ["A1", "A2", "B1", "B2"]
def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [a+b for a in A for b in B]

我花了一段时间思考如何在 Scala 中优雅地做到这一点,这就是我想出的:

// cross("AB", "12") => List[String]("A1", "A2", "B1", "B2")
def cross(r: String, c: String) = {
   for(i <- r; j <- c) yield i + "" + j
}.toList

我只是好奇在 Scala 中是否有更好的方法来做到这一点?如果我能这样做,它看起来会更干净,yield i + j但这会导致Int某种原因。任何意见或建议将不胜感激。

4

1 回答 1

1

是的,加法Char是通过添加它们的整数等价物来定义的。我认为你的代码很好。您还可以使用字符串插值,并保留toList(您将得到一个不可变的索引序列,这很好):

def cross(r: String, c: String) = for(i <- r; j <- c) yield s"$i$j"

编辑

An IndexedSeq is at least as powerful as List. Just check your successive usage of the result. Does it require a List? E.g. do you want to use head and tail and pattern match with ::. If not, there is no reason why you should need to enforce List. If you use map and flatMap on the input arguments instead of the syntactic sugar with for, you can use the collection.breakOut argument to directly map to a List:

def cross(r: String, c: String): List[String] = 
  r.flatMap(i => c.map(j => s"$i$j"))(collection.breakOut)

Not as pretty, but faster than an extra toList.

于 2013-03-29T22:56:57.983 回答