我想知道如何从两个序列中删除重复元素并组合两个序列。例如,
user=>(remove-dup [1 4 7 10 16] [2 7 18 4])
(1 2 10 18 16)
我的代码是:
(defn remove-dup [l1 l2]
(let [list (concat l1 l2)]
(loop [l list res '()]
(if (>= (second (first (frequencies l))) 2)
(recur (rest l) res)
(recur (rest l) (conj res (first (first l))))))))
但是当我运行代码时,我收到了错误消息:
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:528)
如何修复此代码。谢谢!
答案 0 :(得分:6)
您的错误在这里:
int *shiftArray(int *, int, int);
int main()
{
int size = 6;
int *b = new int[size]{ 1, 2, 3, 4, 5, 6 };
int shiftStartIndex = 3;
b = shiftArray(b, size, shiftStartIndex);
int newSize = size - shiftStartIndex;
for (int i = 0; i < newSize; i++)
{
cout << b[i] << " ";
}
cin.ignore();
return 0;
}
int *shiftArray(int *arr, int size, int stIndex)
{
int *a = new int[size - stIndex];
for (int i = 0; i < size - stIndex; i++)
{
a[i] = arr[i + stIndex];
}
delete[] arr;
return a;
}
请记住,(first (first l))
是您尚未处理的所有元素的序列。例如,在l
的第一次迭代中,loop
可能如下所示:
l
您可以从中看到(1 4 7 10 16 2 7 18 4)
将是(first l)
,因此1
会尝试将数字视为序列,但这不起作用。
如果您仅使用(first (first l))
替换(first (first l))
,您将获得(first l)
,因为您没有基本情况:NullPointerException
是什么时候应该做的?空?你可能会这样做(l
是你当前,,,
表达式的占位符):
if
但是,如果我们现在尝试使用该方法,我们仍然无法获得正确的结果:
(if (empty? l)
res
,,,)
槽糕。
我可以尝试更多地使用您的代码来使其工作,但是有更好的方法来解决这个问题。由于您尝试删除重复项并且不关心订单,因此clojure.set
中的函数是此作业的正确工具。我会像这样写(remove-dup [1 4 7 10 16] [2 7 18 4])
;=> (4 18 7 2 16 10 1)
:
remove-dup
示例:
(require '[clojure.set :as set])
(defn remove-dup [c1 c2]
(let [[s1 s2] (map set [c1 c2])]
(seq (set/difference (set/union s1 s2) (set/intersection s1 s2)))))
答案 1 :(得分:2)
您的代码中存在许多致命错误:
打破它的东西是(first (first l))
,因为l
是数字列表,当你尝试取第一项数字时它会引发错误。
但还有更重要的一些:
首先,即使你的代码是正确的,它也没有任何破坏循环的情况,所以它可能会导致无限循环(或某种异常)。其次是你对frequencies
用法的完全误解。您不能依赖frequencies
结果的顺序,因为它返回无序映射(更不用说它是在每次循环迭代中调用的,这对于性能非常糟糕)。
这就是我如何通过循环中的集合传递来做这样的事情:
(defn unique [coll1 coll2]
(let [items (concat coll1 coll2)]
(loop [res #{}
seen #{}
[x & xs :as items] items]
(cond ;; if there are no items left to check, returning result
(empty? items) res
;; if we've already seen the first item of a coll, remove it from the resulting set
(seen x) (recur (disj res x) seen xs)
;; otherwise mark it as seen, and add it to the result set
:else (recur (conj res x) (conj seen x) xs)))))
在repl中:
user> (unique [1 4 7 10 16] [2 7 18 4])
#{1 2 16 10 18}
答案 2 :(得分:0)
(defn remove-dupl [l1 l2]
(let [rmdup (fn [l1 l2] (remove (set l1) l2))]
(concat (rmdup l1 l2) (rmdup l2 l1))))
答案 3 :(得分:0)
试试这个解决方案
(defn remove-dup [l1 l2]
(let [ls (concat l1 l2)]
(loop [l (frequencies ls) res '()]
(if (empty? l) res
(if (>= (second (first l)) 2)
(recur (rest l) res)
(recur (rest l) (cons (first (first l)) res)))))))
答案 4 :(得分:0)
其他人发现了您的错误。我想看看你想做什么。
鉴于此
这是设置操作 exclusive or(XOR)。
它不包含在clojure.set
中。正如Sam Estep所做的那样,我们可以根据我们的操作来定义它,或者自己更直接地写它:
(defn exclusive-or [sa sb]
(if (<= (count sa) (count sb))
(reduce
(fn [ans a]
(if (contains? sb a)
(disj ans a)
(conj ans a)))
sb
sa)
(recur sb sa)))
然后我们可以定义
(defn remove-dup [xs ys]dited
(exclusive-or (set xs) (set ys))
例如,
(remove-dup [1 4 7 10 16] [2 7 18 4]) ;#{1 2 10 16 18}
修改exclusive-or
中的错误。