Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 方案-正确使用cons创建列表_Scheme_Racket_Sicp - Fatal编程技术网

Scheme 方案-正确使用cons创建列表

Scheme 方案-正确使用cons创建列表,scheme,racket,sicp,Scheme,Racket,Sicp,我一直在尝试解决SICP的练习2.20,其中引入了“点尾”符号。我的问题是,我的函数不是返回带有结果的正确列表,而是返回嵌套列表。 我知道我叫犯人的方式有问题,但我仍然不知道如何解决这个问题 这就是我的功能: (define (same-parity first . items) (define (speccar items) (cond ((null? items) 2) ((not (pair? items)) (modulo items 2))

我一直在尝试解决SICP的练习2.20,其中引入了“点尾”符号。我的问题是,我的函数不是返回带有结果的正确列表,而是返回嵌套列表。 我知道我叫犯人的方式有问题,但我仍然不知道如何解决这个问题

这就是我的功能:

(define (same-parity first . items)

  (define (speccar items)
    (cond ((null? items) 2) 
          ((not (pair? items)) (modulo items 2))
          (else (modulo (car items) 2))))

  (define (iter-parity first items result)
    (let ((parityFirst (modulo first 2)) (samepar (speccar items)))
      (if (null? items)
          result
          (if (= parityFirst samepar)
              ;; This next line is where the problem is...
              (iter-parity first (cdr items) (cons (list result) (list (car items))))
              (iter-parity first (cdr items) result)))))

  (iter-parity first items first))
测试:

(same-parity 1 2 3 4 5)
((((1) 3)) 5)
现在,我已经阅读了以下关于类似问题的答案:

他们当然清楚地说明了问题的来源,但如何才能真正实施正确的解决方案呢?
如果可能,Scheme中避免这些陷阱的正确“思考”方式是什么?

您错误地构建了输出列表-请记住:cons的第一个参数应该是当前元素,第二个参数是结果列表

另外,考虑到您使用的是尾部递归,您必须
反转
最后的输出,以保持与原始列表中相同的顺序。试试这个:

(define (same-parity first . items)
  (define (speccar items)
    (cond ((null? items) 2) 
          ((not (pair? items)) (modulo items 2))
          (else (modulo (car items) 2))))
  (define (iter-parity first items result)
    (let ((parityFirst (modulo first 2))
          (samepar (speccar items)))
      (if (null? items)
          (reverse result)
          (if (= parityFirst samepar)
              (iter-parity first
                           (cdr items)
                           (cons (car items) result))
              (iter-parity first
                           (cdr items)
                           result)))))  
  (iter-parity first items (list first)))
如果我们使用内置程序(不要重新发明轮子!),上述解决方案可以大大简化。这是在Scheme中编写程序的推荐方法-遵循函数式:

(define (same-parity head . tail)
  (if (even? head)
      (filter even? (cons head tail))
      (filter  odd? (cons head tail))))
无论哪种方式,它都能按预期工作:

(same-parity 1 2 3 4 5)
=> '(1 3 5)

谢谢你的回答!