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

发布于 2024-08-23 12:25:26 字数 725 浏览 4 评论 0原文

我有以下项目

(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)

这也有效吗?谢谢!

I have the following items

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

My method to find items is below

(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)))
          )
    )
  )

With my method above I can find a1, b2, c3, z1, z2. But when I want to find d5 onwards, it returns nothing. It seems to have skip the stack. Btw, I am just starting to learn Scheme so simple explanation would be better.

One more qns, how about if I have this

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

does this works as well? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

画尸师 2024-08-30 12:25:26

是的,您跳过列表。
示例:

'(1 '(2 3) 4)

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

如果itemlist是一个列表/对,您可以立即在递归调用中传递它
您可以避免在谓词内编写类似 (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

Yes, you skip lists.
Example:

'(1 '(2 3) 4)

If (list? '(2 3)) is true, the else part (outer cond) wont be evaluated so 4 is skipped.
So, either you place the else part inside list? block or you redesign your code.

If the itemlist is a list/pair you can pass it right away in a recursive call so
you can avoid writing code like (car itemslist) inside predicates thus make the code simple.

Here is a redesigned (simplified) version:

(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)))

Tip: you can also can write lists with '(...) notation instead of (list ...), ie

(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
回眸一笑 2024-08-30 12:25:26

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

例如,'(1 (2 3) 4)'(1 . ((2 . (3 . ())) . (4 . ())))< /code> 可以绘制为

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

任意对 (l . r)car 为您提供左树,cdr 为您提供正确的。因此,当您编写 (pair? ls) 时,您实际上是在询问您是否位于树中的一个分支,此时您应该在左侧分支 (car)和右分支(cdr)。希望能帮助您理解列表。

To write more for the sake of writing more... This is usually called a "tree-walk" because a nested list like that is really a binary tree. Lists are really made up of binary pairs, so when you have a pair (l . r), l is the left branch of the tree and r is the right branch of the tree.

For example, '(1 (2 3) 4) is short for '(1 . ((2 . (3 . ())) . (4 . ()))) which can be drawn as

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

and at any pair (l . r), car gets you the left tree and cdr gets you the right. So, when you write (pair? ls), you're really asking if you're at a branch in the tree, at which point you should recur on both the left branch (car) and the right branch (cdr). Hope that helps you understand lists.

薆情海 2024-08-30 12:25:26

即使您得到了[具体]答案,这里的一些内容可能会帮助您解决类似的问题。

(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)))

Even though you got your [specific] answer, here's something that might help you with similar questions.

(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))))

This procedure prints the code that generates a given sexpr. For example:

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

It will also place the quotes where needed, so it places them before symbols or () but not before numbers. When you are comfortable with nested pairs, you may want to remove the #; on the third line, to generate more compact output:

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

This code can teach you many things about quote. For example:

> (describe ''''a)
(list 'quote (list 'quote (list 'quote 'a)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文