Scheme编程在嵌套循环中查找项目

时间:2010-03-05 06:57:36

标签: scheme

我有以下项目

(define itemslist
  (list 'a1 'b2 'c3 (list 'z1 'z2) 'd5 'e6))

我找到项目的方法如下

(define find-item
  (lambda (item itemslist)
    (cond ((null? itemslist) #f)
          ((list? (car itemslist))
            (cond ((null? itemslist) #f)
                  (else (find-item item (car itemslist)))))
          ((equal? stn (car itemslist)) (display "found"))
          (else (find-stn stn (cdr itemslist)))
          )
    )
  )

通过上面的方法,我可以找到a1,b2,c3,z1,z2。但是当我想要找到d5之后,它什么也没有返回。它似乎跳过了堆栈。顺便说一句,我刚刚开始学习Scheme,所以简单的解释会更好。

还有一个qns,如果我有这个怎么样

(list 'a1 'b2 'c3 (list 'z1 (list 'y1 'y2) 'z2) 'd5 'e6)

这也有效吗?谢谢!

3 个答案:

答案 0 :(得分:4)

是的,你跳过列表 例如:

'(1 '(2 3) 4)

如果(list? '(2 3))为真,则else部分(外部cond)将不会被评估,因此会跳过4
因此,要么将else部分放在list?块内,要么重新设计代码。

如果itemlistlist/pair,您可以在递归通话中立即传递 你可以避免在谓词中编写像(car itemslist)这样的代码,从而使代码变得简单。

这是一个经过重新设计(简化)的版本:

(define (find-item item l)
  (cond ((equal? item l) #t)
        ((pair? l) (or (find-item item (car l)) (find-item item (cdr l))))
        (else #f)))

提示:您也可以使用'(...)符号而不是(list ...)来编写列表,即

(find-item 'z2 '('a1 'b2 'c3 '('z1 '('y1 'y2) 'z2) 'd5 'e6))  
#t  
(find-item 'e6 '('a1 'b2 'c3 '('z1 '('y1 'y2) 'z2) 'd5 'e6))  
#t

答案 1 :(得分:2)

为了写更多而写更多...这通常被称为“树行走”,因为像这样的嵌套列表实际上是二叉树。列表实际上由二进制对组成,因此当您有一对(l . r)时,l是树的左分支,r是树的右分支。

例如,'(1 (2 3) 4)'(1 . ((2 . (3 . ())) . (4 . ())))的缩写,可以绘制为

     .
    / \
   1   .
      / \
     /   .
    /   / \
   .   4  ()
  / \ 
 2   .
    / \
   3  ()

并且在(l . r)对,car为您提供左侧树,cdr为您提供权利。所以,当你写(pair? ls)时,你真的在​​问你是否在树的一个分支处,此时你应该在左分支(car)和右分支上重复( cdr)。希望能帮助您理解列表。

答案 2 :(得分:0)

即使你得到了[具体]答案,这里有一些可以帮助你解决类似问题的事情。

(define describe
  (lambda (e)
    (cond #;((list? e)
             `(list ,@(map describe e)))
          ((pair? e)
           `(cons ,(describe (car e))
                  ,(describe (cdr e))))
          ((vector? e)
           `(vector ,@(map describe (vector->list e))))
          ((or (null? e) (symbol? e)) `',e)
          (else e))))

此过程打印生成给定sexpr的代码。例如:

> (describe '(a 2 b 3))
(cons 'a (cons 2 (cons 'b (cons 3 '()))))

它还会将引号放在需要的位置,因此它将它们放在符号或()之前,但不放在数字之前。如果您熟悉嵌套对,则可能需要删除第三行上的#;,以生成更紧凑的输出:

> (describe '(a 2 b 3))
(list 'a 2 'b 3)

这段代码可以教你很多关于引用的东西。例如:

> (describe ''''a)
(list 'quote (list 'quote (list 'quote 'a)))