【问题标题】:take a list and subtract every number of that list, with its next number in Racket取一个列表并减去该列表的每个数字,并在 Racket 中减去它的下一个数字
【发布时间】:2020-12-30 20:47:25
【问题描述】:

给定 Racket 中任意长度的列表,从连续元素的差异的绝对值创建一个新列表。新列表的最后一个元素应该是输入列表的第一个元素和最后一个元素之差的绝对值。

例如:输入 t = (2, 6, 7, 11) 应导致 t' = (4, 1, 4, 9)。

这是我所拥有的:

(define (a-succ t i)
  (cond [(empty? t) empty]
        [(>= i (size t)) t]
        [else
         (cons (abs (- (first t)
                       (first (rest t))))
               (a-succ (rest t) i))]))

问题在于,通过这种方法,我不能用最后一个数字减去列表的第一个数字,因为第一个数字在运行程序后会发生变化。所以我认为需要做的第一步是通过定义一个新函数,用反转的第一个数字减去第一个数字。我只是不知道如何更改列表一次,然后将我的递归函数应用于更改后的列表。

【问题讨论】:

  • 长度为 1 的列表应该产生什么?这是一项家庭作业吗?您的解决方案是否有任何限制?您的解决方案是否必须使用递归? “我已经尝试了很多东西......我只是找不到一个好的方法......”:尽你最大的努力;什么不工作?
  • 应该给出长度为 1 的列表(列表 0)。这是一项旨在通过递归解决的家庭作业。下面是我目前得到的代码。
  • 张贴代码中i的目的是什么?问题描述中没有提到这一点。如果您显示示例函数调用和预期结果(而不是在逗号分隔列表上显示抽象转换),这将很有帮助。另外,size 是什么?您是说length,还是使用#lang racket,或其他学生语言?

标签: recursion scheme racket


【解决方案1】:

尚不清楚为什么在发布的代码中需要参数i。另外,请注意基本情况 (empty? t) 永远不会到达,因为 (>= i (size t)) 总是首先到达。

我通常解决在处理过程中需要修改输入列表的问题的方法是使用named let

(define (pairwise-diff xs)
  (let loop ((cycle (append xs (list (first xs)))))
    (if (< (length cycle) 2)
        '()
        (cons (abs (- (first cycle) (second cycle)))
              (loop (rest cycle))))))

这里,修改后的输入列表(第一个元素添加到列表末尾)绑定到loop 正文中的cycle。一个空的输入列表将产生一个长度为 1 的 cycle,而所有其他输入列表将产生一个长度为 2 或更大的 cycle,因此基本情况是 cycle 小于 2。当 @987654332 @ 小于 2,没有减法,应该返回空列表。否则,处理cycle 的前两项的结果是consed 到处理cycle 其余部分的结果。

你可以通过使用define而不是命名let来完成同样的事情:

(define (pairwise-diff xs)
  (define (helper cycle)
    (if (< (length cycle) 2)
        '()
        (cons (abs (- (first cycle) (second cycle)))
              (helper (rest cycle)))))
  (helper (append xs (list (first xs)))))

这里helper 函数完成实际工作,pairwise-diff 只是使用修改后的输入列表调用helper

示例交互:

scratch.rkt> (pairwise-diff '(2 6 7 11))
'(4 1 4 9)

【讨论】:

    【解决方案2】:

    诀窍是定义一个助手。如果该助手是顶级函数,它需要携带列表的第一个元素:

    (define (a-succ l)
      (asl l (first l) '()))
    
    (define (asl t f r)
      (if (empty? (rest t))
          (reverse (cons (abs (- f (first t))) r))
          (asl (rest t) f (cons (abs (- (first t) (second t))) r))))
    

    但您可以将其设为本地函数,这意味着它可以依赖于知道其父级获得的列表:

    (define (a-succ l)
      (define (asl t r)
        (if (empty? (rest t))
            (reverse (cons (abs (- (first l) (first t))) r))
            (asl (rest t) (cons (abs (- (first t) (second t))) r))))
      (asl l '()))
    

    【讨论】:

      猜你喜欢
      • 2011-06-22
      • 1970-01-01
      • 2022-11-08
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      相关资源
      最近更新 更多