我有几个不同长度的列表,其中包含简单的正整数,例如(2 4 1 3)
,我想检查列表排序后是否所有数字都紧跟在后。这意味着顺序本身并不重要,但是不允许有空格。
(2 4 1 3)
是正确的
(2 4 1 5)
不正确
在我重新发明轮子之前,我想知道是否有一种方法可以对列表进行排序,然后检查第一个元素与第二个元素的区别(依此类推...)是1
。
编辑
我的示例未显示完整的任务。列表不必每次都以1
开头,即(6 8 7 9)
也可以是有效输入。
答案 0 :(得分:7)
您需要检查列表定义的集合是否与mutate()
相同。
通过创建适当长度的bit vector可以轻松完成此操作。
这是列表长度上的 linear ([a:b]
)(需要对其进行一次扫描,以length
和O(n)
进行扫描,并且一次填充位向量),并且需要一些向量的额外临时内存:
min
测试:
(defun range-p (list)
"Check that the list is identical to a..b as a set."
(multiple-value-bind (min len)
(loop for obj in list for len upfrom 0
unless (integerp obj) do (return-from range-p nil)
minimize obj into min
finally (return (values min len)))
(loop
;; 0: not seen this index in list yet
;; 1: already seen this index in list
with indicator = (make-array len :element-type 'bit :initial-element 0)
for obj in list for pos = (- obj min) do
(unless (< pos len)
;; obj out of range
(return-from range-p nil))
(if (zerop (aref indicator pos))
;; obj is being seen for the 1st time; record that
(setf (aref indicator pos) 1)
;; duplicate obj
(return-from range-p nil)))
;; all list elements are unique and in the right range;
;; injectivity + same cardinality for finite sets => surjectivity
t))
排序是线性的((range-p '(2 4 1 3))
==> T
(range-p '(2 4 1 5))
==> NIL
(range-p '(-1 5 3 4 2 1 0))
==> T
(range-p '(-1 5 3 4 3 1 0))
==> NIL
(range-p '(2 4 1 a 5))
==> NIL
),因此显然次优。
答案 1 :(得分:2)
将SDS的答案和Renzo的评论放在一起,最后得出了对我有用的:
WHERE
谢谢!
答案 2 :(得分:0)
您可以使用o(n)
中的某些自然数,例如扫描列表,以数学方式解决此问题,以找到最小,最大,长度和总和,然后使用此公式计算自然数之和
actualMax = min+(length(list)-1)
nSum = ((actualMax -min+1)/2)*(actualMax +min)
nSum-total==0?"yes":"no"
让我们考虑一下
Ex -1 (6,8,7,9) min = 6 actual max = 6+(4-1) = 9,max=9, total = 30 naturalSum = 30 it is true
Ex-2 (6,8,7,10) min = 6 actual max = 6+(4-1) = 9,max=10, total = 31 naturalSum = 30 it is false