消除内部括号会变成空列表,并且不会消除使用缺点 [英] Eliminate inner parenthesis runs into empty list and doesn't eliminate using cons

查看:79
本文介绍了消除内部括号会变成空列表,并且不会消除使用缺点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是消除所有内部括号.

The goal is to eliminate all inner parenthesis.

(展平'((a(b c)d))变成'(a b c d)

(flatten '(a (b c) d)) becomes '(a b c d)

这是我在球拍中的代码

; if slist is null, return empty
; otherwise, if it is a pair, recursively solve car and cdr and concat them
; if it is a symbol, return the symbol

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist)  
        (cons ((flatten (car slist)) (flatten (cdr slist))))]
      [ (symbol? slist) slist])))

正在抱怨

procedure application: expected procedure, given: c; arguments were: ()

这意味着我正在尝试访问空列表的carcdr.

which means I am trying to access car and cdr of an empty list.

I did the trace:
> (flatten '(a (b c) d))
pair?-car-cdr
a
((b c) d)
symbol?
a
pair?-car-cdr
(b c)
(d)
pair?-car-cdr
b
(c)
symbol?
b
pair?-car-cdr
c
()
symbol?
c
(stops here)

跟踪代码很简单-一堆显示.

The trace code is simple - a bunch of displays.

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist) 
        (display 'pair?-car-cdr)
        (newline)
        (display (car slist))
        (newline)
        (display (cdr slist))
        (newline)
        (cons ((flatten (car slist)) (flatten (cdr slist))))]
      [ (symbol? slist) 
         (display 'symbol?)
         (newline)
         (display slist)
         (newline)
        slist])))

我不明白的是,第一个条件(null? slist)是怎么没抓住空列表的?我有两个递归调用.如果确实捕获到空列表,它将转到下一个递归列表{d}.

What I don't understand is how come the first condition (null? slist) didn't catch the empty list? I have two recursive calls. If it did catch the empty list, it would go to the next recursion which is the list {d}.

我的递归逻辑有什么问题?

What is the problem with my recursion logic?

更新版本

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist)  
        (cons (flatten (car slist)) (flatten (cdr slist)))]
      [ (symbol? slist) slist])))

(display (equal? (flatten '(a (b a) b a c (a b) c (e f (b a)))) '(a b a b a c a b c e f b a)))
(newline)
(display (equal? (flatten '(a b c)) '(a b c)))
(newline)
(display (equal? (flatten '(a (b c))) '(a b c)))
(newline)
(display (equal? (flatten '((a)(b)(c) d)) '(a b c d)))
(newline)
(display (equal? (flatten '(a (b) ((c)) (((d))) ((((e (f g))))))) '(a b c d e f g )))
(newline)
(display (equal? (flatten '()) '()))
(newline)
(display (equal? (flatten '(a b () ())) '(a b)))
(newline)

正如罗斯·拉森(Ross Larson)所建议的,append可使程序正常工作.但是为了学习,如果有人有时间,我的测试结果仅显示通过的基本案例(第二个和空列表)

As Ross Larson suggested, append will make the program works. But for the sake of learning, if any one have the time to spare, the result of my tests show only the base cases passed (2nd and the empty list)

我考虑编写一个调用(cons (flatten slist) empty)

推荐答案

问题是这个表达式:

(((拉平汽车)...)

((flatten (car slist)) ...)

这意味着应用任何(展平...)返回值.但是既然这样 返回列表,应用程序将失败.

This means, apply whatever (flatten ...) returns. But since this returns a list, the application fails.

将其更改为

(拉平(汽车驻车道))

(flatten (car slist))

这篇关于消除内部括号会变成空列表,并且不会消除使用缺点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆