繁体   English   中英

方案:返回可以使用car和cdr的任意组合获得的表达式的所有元素

[英]Scheme: Return all elements of an expression that can be obtained using any combination of car and cdr

我正在尝试在CS类的Scheme(R5RS)中编写一个过程,该过程将一个表达式(符号或列表)作为参数并返回(1)的所有可能表达式的列表,这些表达式可以通过使用car和cdr代表表达式(2)和一个表达式,说明如何获得原始表达式的这些组成部分。 如果可以通过多种方式获得一件作品,则应将其退回不止一次。

Examples

(pieces '()) => ((() x))

(pieces 'apple) =>  ((apple x))

(pieces '(apple)) => (((apple) x) (apple (car x)) (() (cdr x)))

(pieces '(a (b c))) =>
               (((a (b c)) x)
                (a (car x))
                (((b c)) (cdr x))
                ((b c) (car (cdr x)))
                (b (car (car (cdr x))))
                ((c) (cdr (car (cdr x))))
                (c (car (cdr (car (cdr x)))))
                (() (cdr (cdr (car (cdr x)))))
                (() (cdr (cdr x))))

由于我们刚刚开始使用Scheme,因此仅限于此分配的相当基本的语法。 这是我到目前为止的内容:

(define pieces
  (lambda (exp)
    (cond
      ((symbol? exp)
       (list exp 'x))
      ((null? exp)
       (list '() 'x))
      ((list? exp)
       (let ((b (pieces (car exp))) (c (pieces (cdr exp))))
          (list exp 'x b c))))))

(pieces '()) => (() x)

(pieces 'apple) => (apple x)

(pieces '(apple)) => ((apple) x (apple x) (() x))

(pieces '(a (b c))) => ((a (b c)) x (a x) (((b c)) x ((b c) x (b x) ((c) x (c x) (() x)))
                       (() x)))

该过程返回所有适当的元素,但是每次递归都会使这些组件嵌套在其他列表中。 有什么办法可以防止这种情况?

另外,我不知道问题的第二部分从哪里开始(显示如何使用car和cdr从原始元素中获取每个元素)。 我已经尝试了上百万种不同的方法,但是没有一个方法接近于可行。 如果有人对如何实现该功能有任何提示或建议,我将非常感谢。 万分感谢。

(pieces 'apple) => (apple x)

但这应该是((apple x)) ,对吗? 您应该得到一个列表,其中第一个也是唯一的元素是列表(apple x)

终止递归的cond子句(exp是符号或null)将返回应包含在列表中的项目,而在carcdr上递归的子句则尝试创建项目列表。 由于pieces既可以返回项目又可以返回项目列表,因此很难根据从其返回的值中列出项目:当您这样做(list exp 'xbc)您不知道bc是否为项目应该进入一个或多个项目列表。

如果您确保pieces始终返回项列表(例如(list (list exp 'x)) ),则变得容易得多。 当您再次使用carcdr您想要执行类似append列表ab然后将“当前”( (list exp 'x) )项添加到该列表中(可能包含cons或其他内容)。

对于第二部分, pieces必须知道如何到达当前项目。 您可以使pieces采用到当前项目的“路径”作为(可能是可选的)参数。 如果路径是一个列表,那么当你调用pieces(car exp)你可以添加一个car象征你发送作为参数的路径,以及(cdr exp)可以添加符号cdr 然后,使用该路径创建一些不错的东西来代替'x in (list exp 'x)

我知道这不是Scheme,但也许看看类似的语言会有所帮助。 我做了更多这样的练习来练习自己,所以滴一滴盐就可以了,但它似乎完全可以满足您的要求:

(defun parse-list (whatever)
  (labels ((pieces (expression &optional path)
         (cond
           ((null expression)
        `((,path . nil)))
           ((listp expression)
        (append (list
             `(,path . ,expression))
            (pieces (car expression)
                (cons 'car path))
            (pieces (cdr expression)
                (cons 'cdr path))))
           (t `((,path . ,expression))))))
    (dolist (output (pieces whatever))
      (format t "path ~a => result ~a~&"
          (car output) (cdr output)))))

(parse-list '(a (b c)))

然后产生以下输出:

path NIL => result (A (B C))
path (CAR) => result A
path (CDR) => result ((B C))
path (CAR CDR) => result (B C)
path (CAR CAR CDR) => result B
path (CDR CAR CDR) => result (C)
path (CAR CDR CAR CDR) => result C
path (CDR CDR CAR CDR) => result NIL
path (CDR CDR) => result NIL

抱歉,我无法获得比这更好的SO的代码格式:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM