【问题标题】:Upper-triangular loop idiom for Scala ListsScala 列表的上三角循环习惯用法
【发布时间】:2013-09-09 21:13:28
【问题描述】:

从我的命令式编程背景来看,我已经习惯了

for (i = 0;  i < 1000000;  i++) {
    for (j = i + 1;  j < 1000000;  j++) {
        doSomething(array[i], array[j])
    }
}

检查一百万个元素数组中的所有唯一对。 doSomething 是一些在对角线和对称或反对称的对角线结果上产生微不足道结果的操作——这就是我只想处理上三角形的原因。 (i == j 的情况很有趣;这很容易解决。)

我发现自己奇怪地被困在 Scala 中尝试这样做。我有一个很大的List 并且想对所有成对组合做点什么,但是

list.flatMap(x => list.map(y => doSomething(x, y))

包括所有多余或琐碎的情况(工作量的两倍)和

(0 until 1000000).flatMap({i =>
  (0 until 1000000).map({j =>
    doSomething(list(i), list(j))
  })
})

将是非常错误的,因为列表不是随机访问(N^2 的工作量太大)。我可以将我的Lists 转换为Arrays,但感觉好像没有抓住重点。 Lists 是链表,所以我的命令式示例中的 j + 1 元素距离我目前正在检查的 i 仅一步之遥。我确信我可以在 C/Python/whatever 中的链表上编写一个高效的上三角循环。

我想我现在只能吞下 2 的因素,但这是一种很常见的情况,感觉应该有一个很好的解决方案。

另外,这个“上三角环”有一个通用名称吗?我找不到合适的搜索字符串。

编辑:下面是一个错误解决方案的例子:

list.zipWithIndex.flatMap({case (x, i) =>
  list.zipWithIndex.map({case (y, j) =>
    if (j > i)
      doSomething(x, y)
    else
      Nil
  })
})

因为它仍然会访问不需要的节点。

【问题讨论】:

    标签: scala nested-loops functor


    【解决方案1】:

    您可能想查看Vector 数据类型,它允许基于索引的快速查找。

    此外,还有一种内置组合方法,可以为您提供所需的外观。

    scala> (1 to 3).combinations(2).mkString(" ")
    res1: String = Vector(1, 2) Vector(1, 3) Vector(2, 3)
    

    【讨论】:

    • 谢谢! combinations 是我要找的。我查看了 Scala 文档,描述非常简短,我并不为我之前没有找到它而感到尴尬。
    • 这很酷,但它仅在我们使用 (1 到 3) 时才有效。如果我想要列表中具有重复值的组合怎么办?我应该用它来索引吗?我想像这样使用生成器进行迭代......
    • Vector(1,2,2,3).combinations(2).mkString(" ") 将为您提供重复的预期结果。
    • 如果 Vector(1,1,1,1).combinations(2).toList 的预期结果是 List(Vector(1, 1)),那么可以。但如果您期望该列表中有 6 个项目,则不是。
    【解决方案2】:

    您可以通过以下方式使用模式匹配和尾递归:

    @tailrec def walk[T](list: Seq[T]): Unit =
      list match {
        case head :: tail =>
          tail.foreach(doSomething(head, _))
          walk(tail)
        case Nil =>
      }
    

    【讨论】:

    • 谢谢!虽然这真的很聪明,但我宁愿使用内置的仿函数。这可能是combinations 在内部实现的方式。
    【解决方案3】:

    关于这部分问题:

    另外,这个“上三角环”有一个通用名称吗?我找不到合适的搜索字符串。

    “上三角环”的通用名称是三角矩阵。 (如wikipedia 中所述)

    ...三角矩阵是一种特殊的方阵。如果主对角线以上的所有项都为零,则方矩阵称为下三角矩阵。类似地,如果主对角线以下的所有项都为零,则方阵称为上三角矩阵。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多