【发布时间】:2020-08-15 03:21:29
【问题描述】:
我正在开发一个 Clojure 项目,该项目将数组 a 作为输入,并在 [i,j] 范围内为每个 i、j、O(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”的值!非常感谢您的帮助!