【问题标题】:Sparsely populated multidimensional vector in clojure?Clojure中人口稀少的多维向量?
【发布时间】:2011-04-29 16:12:26
【问题描述】:

我试图在 Clojure 中创建一个人口稀少的多维向量,但我遇到了我知识的限制。

我有一个集合x 我正在迭代,我想通过(count x) 创建一个大小为(count x) 的多维向量。大多数单元格将为空,但在 x 轴和 y 轴匹配的每个点(例如,(1 1)、(2 2)、(3 3)等),我需要运行一个函数来查看是否应该在该空间中放置一个值。

在程序语言中,它会是这样的:

for (i = 0; i < length(x); i++) {
    for (j = 0; j < length(x); j++) {
        if (i == j && testReturnsTrue(x[i])) {
            table[i][j] = (list x[i])
        }
        else {
            table[i][j] = ()
        }
    }
}

但我无法理解如何在 Clojure 中完成此操作。我尝试使用嵌套的理解和嵌套的循环递归结构,但我都无法工作。

或者,我可以创建一个具有正确大小的可变表,将其全部初始化为空列表,然后在检查x 中的每个元素时设置值,但如果可能,我希望保持该表不可变.

【问题讨论】:

  • FWIW 你用“稀疏”这个词来表示显然让所有回答的人感到困惑的东西。如果您的向量稍后将被填充并且只是稀疏现在,那么面向稀疏的技术将没有多大意义。我建议您更改或澄清问题。

标签: clojure


【解决方案1】:

使用哈希图?不需要向量,它不能是稀疏的。另外,这个命令式的解决方案看起来也不是稀疏的——它浪费了存储大量空单元格的内存。也许是这样的:

(let [indexed (map-indexed vector xs)]
  (reduce (fn [m [i x]]
            (if (test? x)
              (assoc-in m [i i] x)
              m))
          {}
          indexed))

【讨论】:

    【解决方案2】:

    嵌套fors 是我的做法:

    (def x [:a :b :c :d])
    (vec (for [i (range (count x))]
           (vec (for [j (range (count x))]
                  (if (and (= i j) (identity (x i)))
                    [(x i)]
                    [])))))
    => [[[:a] [] [] []] [[] [:b] [] []] [[] [] [:c] []] [[] [] [] [:d]]]
    

    (identity (x i)) 是某种测试的替代品。

    编辑:如其他答案中所述,如果此结构仍然稀疏,则哈希映射是更好的选择。我假设您将在以后的计算中填充空白部分。

    【讨论】:

    • 太好了,谢谢!我将填充表格的其余部分,这只是对角线中放置数据的第一次传递。
    • 即使您确实填充了其余部分,哈希图至少也一样好,除非您想按数字顺序遍历键。如果你所做的只是随机访问,我认为哈希图更清晰。
    猜你喜欢
    • 2013-10-12
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2020-01-02
    • 2011-02-26
    相关资源
    最近更新 更多