【问题标题】:Range Minimum Query - Clojure范围最小查询 - Clojure
【发布时间】:2020-08-15 03:21:29
【问题描述】:

我正在开发一个 Clojure 项目,该项目将数组 a 作为输入,并在 [i,j] 范围内为每个 ijO(n) 预处理和 @ 找到最小值987654327@ 用于每个查询。 (预处理需要O(n*log(n)),但通过使用并发(pmap)并将数组划分为n/log n数组,我们可以在O(n)中解决这个问题)

所以,我选择将数组表示为向量,将矩阵表示为向量的向量。

这是 C# 中的函数之一:

    void build_RMQ_log(int[] a)
    {
        ST = new int[2 * a.Length][];
        for (int i = 0; i < 2 * a.Length; i++)
            ST[i] = new int[(int)Math.Log(a.Length, 2)];

        for (int i = 0; i < a.Length; i++)
        {
            ST[i][0] = i;
            ST[i + a.Length - 1][0]=0;
        }

        for (int j = 1; j < (int)Math.Log(a.Length, 2); j++)
        {
            for (int i = 0; i < a.Length; i++)
            {
                if (a[ST[i][j - 1]] <= a[ST[i + (int)Math.Pow(2, j - 1)][j - 1]])
                    ST[i][j] = ST[i][j - 1];
                else
                    ST[i][j] = ST[i + (int)Math.Pow(2, j - 1)][j - 1];
            }
        }
    }
    i

这就是我在 Clojure 中的编写方式:

    ;build_RMQ_log(int[] a)

    (defn check [row1 row2 arr j]
                  (let [x1 (nth arr (nth row1 j))
                    x2 (nth arr (nth row2 (- j 1)))
                    x3 (nth arr (nth row1 (- j 1)))]

                  (if (<= x1 x2)
                     (assoc row1 j (nth row1 (- j 1)))
                     (assoc row1 j (nth row2 (- j 1))))))

    (defn apply_fn [ST a row r]
    (let [len (count a)
     cnt (/ len (log_ len 2))]
      (loop[ii 0 r 0]
        (if (= ii (- cnt 1))
          ST
         (recur (inc ii) (check row (nth ST (+ r (Math/pow 2 (- ii 1)))) a ii))))))


   (defn build_RMQ_log [a]
     (let [len (count a)
           ST (diag_n_m len (log_ len 2))
           r 0]
     (pmap  (fn [row] (apply_fn (ST a row r))) ST )))

首先,当我尝试运行它时,它显示了这个错误:

    #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of  args (3) passed to: PersistentVector>

此外,我写的代码没有做我想要的,因为如果apply_fn 并行工作,我不知道如何更改r 的值(表示行号)。 IE。喜欢它在 c# 中的变化:

for (int i = 0; i < a.Length; i++)

r 就像 c# 中 for-loop 中的 i

提前致谢。

【问题讨论】:

  • 想必这和这个问题是一样的:stackoverflow.com/questions/9261473/rmq-function-implementation 我建议你先尝试在没有并行性的情况下实现这个功能,然后在你第一次得到后修改它以使用pmap它工作正常。
  • 我们再次尝试了同样的错误,但不知道如何更改“r”的值!非常感谢您的帮助!

标签: c# clojure rmq


【解决方案1】:

如果我没有正确理解您,您希望将递增的r 传递给apply_fn 的每个调用。你可以试试这个:

(defn build_RMQ_log [a]
  (let [len (count a)
        ST (diag_n_m len (log_ len 2))
        rs (range)]
    (pmap  (fn [row r] (apply_fn (ST a row r))) ST rs)))

也就是说,您将两个集合传递给pmap,其中第二个集合是递增整数的无限集合(即[0, 1, 2, 3, ...])。

【讨论】:

  • 非常感谢,这解决了我的第二个问题。我添加了以下代码: (defn inc_int_arr [x] (def m3 []) (def x1 (dec x)) (loop[i 0] ( if(and (not(= (def m3 (conj m3 i)) [])) (= i x1)) m3 (recur (inc i))))) (defn build_RMQ_log [a] (let [len (count a ) ST (diag_n_m len (log_len 2)) r (inc_int_arr len)] (pmap (fn [row r] (apply_fn (ST a row r)))ST))) 这应该有效,但它向我展示了以下内容当我尝试运行 build_RMQ_log 时出错:#
  • 您的pmap 调用仅将一个参数传递给(fn),它需要两个参数。另外,请停止在函数定义中使用def
  • 对。好吧,这是我在 Clojure 中的第一个项目。感谢您的帮助,希望它现在可以工作。
猜你喜欢
  • 2015-10-02
  • 1970-01-01
  • 2013-10-23
  • 2016-03-02
  • 1970-01-01
  • 2013-01-24
  • 2021-08-17
  • 2017-01-16
相关资源
最近更新 更多