我正在尝试实现一个递归函数,将每个数字转换为N,每个符号转换为S,每次找到子列表时,在子列表的开头和结尾添加字符I和D.
示例:(令牌'(1(a(2b)5)))=> (N I S I N S D N D D)
现在我已经有了这段代码:
;delete parentheses
(define (delete atm lis)
(cond
((null? lis) '())
((symbol? lis) lis)
((eq? atm (car lis)) (delete atm (cdr lis)))
(else (cons (car lis) (delete atm (cdr lis))))))
(define (tok l)
(cond [(null? l) ()]
[(number? (car l)) (cons 'N (tok (cdr l)))]
[(symbol? (car l)) (cons 'S (tok (cdr l)))]
[ else (cons (cons 'I (tok (car l))) (cons (tok (cdr l)) (cons 'D '())))]
))
(define (tokens l)
(delete '() (tok l))
)
答案 0 :(得分:1)
你打电话给什么"删除括号"通常被称为" flattening" - 从嵌套列表创建一个平面列表。因此,最好的开始是一个有效的flatten
程序;我最喜欢的是以下内容:
(define (flatten sxp)
(let loop ((sxp sxp) (res '()))
(cond
((null? sxp) res)
((pair? sxp) (loop (car sxp) (loop (cdr sxp) res)))
(else (cons sxp res)))))
测试:
> (flatten '(1 (a (2 b) 5)))
'(1 a 2 b 5)
现在我们还需要做两件事:
'N
,将符号替换为'S
'I
和'D
对于第1部分,这是上述else
的{{1}}部分的一个小变化:
cond
第2部分比较复杂,具体取决于您的(else (cons (cond
((number? sxp) 'N)
((symbol? sxp) 'S)
(else sxp))
res)))))
程序。我在cons单元上工作,因此子列表的开始由cons单元的flatten
标识为列表。 car
的冗余使用被(car sxp)
表达式中c
的绑定所取代:
let
全部包装:
((pair? sxp) (let ((c (car sxp)))
(if (list? c)
(cons 'I (loop c (cons 'D (loop (cdr sxp) res))))
(loop c (loop (cdr sxp) res)))))
测试:
(define (tokens sxp)
(let loop ((sxp sxp) (res '()))
(cond
((null? sxp) res)
((pair? sxp) (let ((c (car sxp)))
(if (list? c)
(cons 'I (loop c (cons 'D (loop (cdr sxp) res))))
(loop c (loop (cdr sxp) res)))))
(else (cons (cond
((number? sxp) 'N)
((symbol? sxp) 'S)
(else sxp))
res)))))
请注意,由于> (tokens '(1 (a (2 b) 5)) )
'(N I S I N S D N D)
和'D
应该达到平衡,因此我的示例比您的示例少'I
。
答案 1 :(得分:1)
做到了!
(define (tokens l)
(cond [(null? l) ()]
[(number? (car l)) (cons 'N (tokens (cdr l)))]
[(symbol? (car l)) (cons 'S (tokens (cdr l)))]
[ else (append (append (cons 'I (tokens (car l))) (cons 'D '())) (tokens (cdr l)))]
))