如何检查列表中的所有数字是否都在稳定增加?

时间:2019-02-10 20:13:49

标签: list numbers common-lisp

我有几个不同长度的列表,其中包含简单的正整数,例如(2 4 1 3),我想检查列表排序后是否所有数字都紧跟在后。这意味着顺序本身并不重要,但是不允许有空格。

(2 4 1 3)是正确的

(2 4 1 5)不正确

在我重新发明轮子之前,我想知道是否有一种方法可以对列表进行排序,然后检查第一个元素与第二个元素的区别(依此类推...)是1

编辑

我的示例未显示完整的任务。列表不必每次都以1开头,即(6 8 7 9)也可以是有效输入。

3 个答案:

答案 0 :(得分:7)

最佳解决方案

您需要检查列表定义的集合是否与mutate()相同。 通过创建适当长度的bit vector可以轻松完成此操作。 这是列表长度上的 linear [a:b])(需要对其进行一次扫描,以lengthO(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 ),因此显然次优。

PS

这可能与Check consecutive numbers recursively using Lisp有关。

答案 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