簡體   English   中英

范圍最小查詢 - Clojure

[英]Range Minimum Query - Clojure

我正在一個Clojure的項目,作為輸入的陣列a ,並且在范圍內發現的最低[i,j]為每個ij ,在O(n) preproccessing,和O(1)為每個查詢. (預處理需要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的值(代表行號)。 即喜歡它在 c# 中的變化:

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

r就像 c# 中for循環中的i

提前致謝。

如果我理解正確,您希望將遞增的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, ...] )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM