Lisp反转元素的所有连续序列

Mocktheduck

我只想反转连续序列,而不是原始列表中的所有元素。

 Ex:
    (reverseC '( 1 2 ( 4 5 ) 5 ) ) => ( 2 1 ( 5 4 ) 5 )
    (reverseC '(1 4 2 (3 4) 9 6 (7 8)))) => (2 4 1 (4 3) 6 9 (8 7))

我当时正在考虑将其拆分为2个功能:一个功能反转一个简单列表(1 2 3)->(3 2 1)和一个功能(主要)来确定连续序列,从中创建一个列表,然后对该列表,然后重新制作整个反向列表。

(defun reverse-list ( lista ) 
    (if (eql lista () )
        ()
        (append (reverse-list (cdr lista )) (list ( car lista)))
    )
)

这是反向功能,但我不知道该如何做另一项。我是Lisp的新手,我来自Prolog,所以这是一个非常大的景观更改。任何想法都欢迎。

(defun reverse-more (L)
    (if (eql L nil)
        nil
        (let ( el (car L)) (aux (cdr L)))
        (if (eql (listp el) nil)
     ...No idea on the rest of the code ...
核心转储

您可以使用单个递归函数一次执行所有操作,并且通常会发出警告,与递归方法相比,您应该更喜欢循环构造(请参见下文):

(defun reverse-consecutive (list &optional acc)
  (etypecase list

    ;; BASE CASE
    ;; return accumulated list
    (null acc)

    ;; GENERAL CASE
    (cons (destructuring-bind (head . tail) list
            (typecase head
              (list
               ;; HEAD is a list:
               ;;
               ;; - stop accumulating values
               ;; - reverse HEAD recursively (LH)
               ;; - reverse TAIL recursively (LT)
               ;;
               ;; Result is `(,@ACC ,LH ,@LT)
               ;;
               (nconc acc
                      (list (reverse-consecutive head))
                      (reverse-consecutive tail)))

              ;; HEAD is not a list
              ;;
              ;; - recurse for the result on TAIL with HEAD
              ;;   in front of ACC
              ;;
              (t (reverse-consecutive tail (cons head acc))))))))

例子

(reverse-consecutive '(1 2 (3 4) 5 6 (7 8)))
=> (2 1 (4 3) 6 5 (8 7))

(mapcar #'reverse-consecutive
        '((1 3 (8 3) 2 )
          (1 4 2 (3 4) 9 6 (7 8))
          (1 2 (4 5) 5)))

=> ((3 1 (3 8) 2)
    (2 4 1 (4 3) 6 9 (8 7))
    (2 1 (5 4) 5))

备注

@ Melye77该destructuring-bind表达式与[Head|Tail] = ListProlog中的功能相同我本可以写这个

(let ((head (first list)) 
      (tail (rest list)))
 ...)

同样,我更倾向于尽可能使用(e)typecase泛型cond表达式,因为我认为它更精确。

我可以写:

(if acc
    (if (listp (first list))
      (nconc ...)
      (reverse-consecutive ...))
    acc)

...但是我认为这对初学者来说不太清楚,也不是一件好事。相反,我认为,介绍(尤其是对于初学者而言)介绍所有可用的构造都是有用的。例如,实际上不建议过度使用递归函数:对于序列而言,有很多现有的迭代构造不依赖于尾部调用优化的可用性(尽管通常可以通过适当的声明来使用,但不能保证实现这些优化) 。

迭代版

这是使用标准reversenreverse功能的迭代版本与上述方法相反,内部列表被简单地反转(仅在深度的第一级别检测到连续的块):

(defun reverse-consecutive (list)
  (let (stack result)
    (dolist (e list (nreverse result))
      (typecase e
        (list
         (dolist (s stack)
           (push s result))
         (push (reverse e) result)
         (setf stack nil))
        (t (push e stack))))))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

CSS反转元素下方的所有内容

从数组生成所有连续序列

在O(n)时间中找到序列的最长连续子序列的长度,其中所有元素均小于10 ^ 6

获取数组元素的所有有序、连续组合

Lisp-替换列表中元素的所有外观

如何从列表中删除所有连续的相等元素?

替换列表中所有连续且重复的Python元素

从序列创建所有固定长度的不连续子序列

从列表中提取所有n元素序列

从序列中删除所有重复元素

从可排序列表中获取所有元素属性

如何获取我的JavaScript数组的所有子字符串(连续的子序列)?

如何获取数组中所有连续数字的范围(增加子序列)?

获取指定大小的所有连续子序列,同时也环绕到前面

如何从字符串中收集所有可能的连续单词序列?

如何找到数组中连续零序列的所有第一个索引?

每个元素小于 3 的最长连续序列

生成最长的位序列,其中所有5位连续子序列都是唯一的

在所有元素都来自{1,2,…,n}集的数组中,哪个数组的反转次数最多?它有多少个反转?

Common Lisp-将函数应用于列表中的所有其他元素

检查集合中包含的所有元组中的给定整数元素是否连续

收集CSV文件中唯一元素的所有索引并连续填充它们

如何使所有元素连续位于同一高程上

找到第一个索引,使所有连续元素均为零

仅使用队列查找大小为 K 的所有连续子数组中的最大元素

拆分3D numpy数组以获取具有满足条件的连续值的所有序列

Qt反转所有小部件的位置

C ++反转fstream中的所有位

Python:读取文件并反转所有行

TOP 榜单

热门标签

归档