在有一些限制的情况下反转Scheme中的列表

发布于 2025-01-17 05:11:38 字数 667 浏览 1 评论 0原文

我正在尝试反转Scheme中的列表,但我只能使用definecarcdrlist?,<强>空?,<强>如果,<强>条件,<强>缺点,<强>显示,< strong>开始,以及任何运算符。我不能使用追加、循环(必须是纯递归)、lambda 和任何其他我没有提到的函数。我也不允许使用辅助函数。一切都应该在一个功能中。

现在已经过去几个小时了,我已经尝试了多种解决方案,但仍然无法解决这个问题。这是我得到的最接近的解决方案:

(define (my-reverse2 lis)
    (if (null? (cdr lis)) lis
        (cons (my-reverse2 (cdr lis)) (cons (car lis) '()))))

这是输出:

> (my-reverse2 '(3 2 1))
Output: (list (list (list 1) 2) 3)

输出应该类似于 (1 2 3)。我应该如何进行?

I'm trying to reverse a list in Scheme, but I can only use define, car, cdr, list?, null?, if, cond, cons, display, begin, and any operators. I cannot use append, loops (must be pure recursion), lambda and any other functions that I have not mentioned. I'm also not allowed to use helper functions. Everything should be in one function.

It's been hours now and I've tried multiple solutions and I still cannot solve this. This is the closest solution that I got:

(define (my-reverse2 lis)
    (if (null? (cdr lis)) lis
        (cons (my-reverse2 (cdr lis)) (cons (car lis) '()))))

And this is the output:

> (my-reverse2 '(3 2 1))
Output: (list (list (list 1) 2) 3)

The output should be something like (1 2 3). How should I proceed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

腹黑女流氓 2025-01-24 05:11:38

最简单的方法是使用累加器值:

(define (my-reverse the-list acc)
  (if (null? the-list)
      acc
      (my-reverse (cdr the-list)
                  (cons (car the-list) acc))))

您将其称为 (my-reverse '(1 2 3) '())。如果Scheme中有可选参数,您可以将acc设为可选,默认值为空列表。在我的代码中,我通常会对此进行包装,仅使用单个参数,然后使用空列表调用两个参数版本。

The easiest way would be to use an accumulator value:

(define (my-reverse the-list acc)
  (if (null? the-list)
      acc
      (my-reverse (cdr the-list)
                  (cons (car the-list) acc))))

You call this (my-reverse '(1 2 3) '()). If there were optional arguments in Scheme you could make the acc optional with a default value of the empty list. In my code I would usually have a wrapper around this with a single argument only which then calls the two argument version with the empty list.

梦里泪两行 2025-01-24 05:11:38

首先,反转 cdr 并获取其 car ——这将是......最后元素,对吗? -- 其cdr 将是相反的core,即没有最后一个和第一个元素的原始列表。

然后,将原始carcons到反转的核心上,反转,从而按原始顺序获取列表中除最后一个元素之外的所有元素。那么现在我们可以反转那个,并将最后一个元素cons到结果上。

很简单,对吧?是的,没那么多。所以这里有一个例子:

a b c ...... m n                                         ; car, cdr:
  b c ...... m n                                         ; reversen-1:
|              n m ...... c b                            ; car, cdr:
|                m ...... c b                            ; reversen-2:
|              |            b c ...... m                 ; cons a:
a              |            b c ...... m                 ; reversen-1:
               |                       m ...... c b a    ; cons n:
               n                       m ...... c b a    ; =: reversen

所有这些需要的是 cdr, car, cons, null?, cond 和递归。 let/define 会有很大帮助,但并不是绝对必要的。不要忘记处理极端情况。

另请参阅:这个我的相关答案。

First, reverse the cdr and take its car -- which will be ... the last element, right? -- and its cdr will be the reversed core, i.e. the original list without its last and first element.

Then, cons the original car onto the reversed core, reversed, thus getting all the elements of the list without the last one, in original order. So then now we can reverse that, and cons the last element onto the result.

Simple, right? Yeah, not so much. So here's an illustration:

a b c ...... m n                                         ; car, cdr:
  b c ...... m n                                         ; reversen-1:
|              n m ...... c b                            ; car, cdr:
|                m ...... c b                            ; reversen-2:
|              |            b c ...... m                 ; cons a:
a              |            b c ...... m                 ; reversen-1:
               |                       m ...... c b a    ; cons n:
               n                       m ...... c b a    ; =: reversen

All this needs is cdr, car, cons, null?, cond, and recursion. let/define will help a lot but is not strictly necessary. Do not forget to take care of the corner cases.

See also: this related answer of mine.

泪是无色的血 2025-01-24 05:11:38

可能是有史以来效率最低的reverse,但它确实符合您问题中的标准。在本练习结束时,您应该能够相当轻松地纯粹从 carcdr 角度思考 -

(define (reverse t)
  (if (null? t)
      t
      (if (null? (cdr t))
          t
          (cons (car (reverse (cdr t)))
                (reverse
                 (cons (car t) 
                       (reverse
                        (cdr (reverse (cdr t))))))))))
(reverse '(1 2 3 4 5 6 7 8 9))
'(9 8 7 6 5 4 3 2 1)

好吧,dangit,这基本上就是 @WillNess 写的 :D

If let 被允许,你可以删除两个 (reverse (cdr t)) 实例 -

(define (reverse t)
  (if (null? t)
      t
      (if (null? (cdr t))
          t
          (let ((q (reverse (cdr t))))
            (cons (car q)
                  (reverse (cons (car t)
                                 (reverse (cdr q)))))))))

如果允许 or,我们可以折叠两个 if -

(define (reverse t)
  (if (or (null? t) (null? (cdr t)))
      t
      (let ((q (reverse (cdr t))))
        (cons (car q)
              (reverse (cons (car t)
                             (reverse (cdr q))))))))

Probably the most inefficient reverse ever written but it does meet the criteria in your question. By the end of this exercise you should be fairly comfortable thinking purely in terms of car and cdr -

(define (reverse t)
  (if (null? t)
      t
      (if (null? (cdr t))
          t
          (cons (car (reverse (cdr t)))
                (reverse
                 (cons (car t) 
                       (reverse
                        (cdr (reverse (cdr t))))))))))
(reverse '(1 2 3 4 5 6 7 8 9))
'(9 8 7 6 5 4 3 2 1)

Well dangit, this is basically what @WillNess wrote :D

If let is allowed, you can remove two instances of (reverse (cdr t)) -

(define (reverse t)
  (if (null? t)
      t
      (if (null? (cdr t))
          t
          (let ((q (reverse (cdr t))))
            (cons (car q)
                  (reverse (cons (car t)
                                 (reverse (cdr q)))))))))

If or is allowed, we can collapse the two if -

(define (reverse t)
  (if (or (null? t) (null? (cdr t)))
      t
      (let ((q (reverse (cdr t))))
        (cons (car q)
              (reverse (cons (car t)
                             (reverse (cdr q))))))))
最单纯的乌龟 2025-01-24 05:11:38

您可以使用可选参数吗?

(define (my-reverse lst [lst2 '()])
  (if (null? lst) lst2
      (my-reverse (cdr lst)
                  (cons (car lst) lst2))))

测试:

> (my-reverse '(3 2 1))
'(1 2 3)

Are you allowed to use optional arguments?

(define (my-reverse lst [lst2 '()])
  (if (null? lst) lst2
      (my-reverse (cdr lst)
                  (cons (car lst) lst2))))

Test:

> (my-reverse '(3 2 1))
'(1 2 3)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文