我正在一個Clojure的項目,作爲輸入的數組a
,發現最小的範圍內[i,j]
每個i
,j
,在O(n)
preproccessing,並O(1)
爲每個查詢。 (preproccessing需要O(n*log(n))
,而是通過使用併發(pmap
)並且將所述陣列n/log n
陣列我們能夠解決在O(n)
這個問題)範圍最小查詢 - Clojure的
所以,我choce代表陣列作爲向量和矩陣的矢量向量。
這是在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>
之外,我寫的代碼不會做我想做的,因爲我不知道我怎樣才能改變VAL如果apply_fn
並行工作,則表示r
(表示行號)。即像它改變在C#:
for (int i = 0; i < a.Length; i++)
(r
就像在C#for
-loop i
)
由於提前。
大概這和這個是一樣的問題:http://stackoverflow.com/questions/9261473/rmq-function-implementation我建議你嘗試先實現沒有並行性的函數,然後修改它以使用'pmap'一旦你第一次得到它正常工作。 – liwp 2012-02-14 09:50:16
我們再次嘗試過,得到相同的錯誤,不知道如何更改「r」的值! 將不勝感激您的幫助! – 2012-02-14 10:12:43