方案比较项目或列表是否在测试列表内(可以嵌套)

发布于 2024-08-05 07:51:25 字数 391 浏览 2 评论 0原文

我的目标是,如果列表或项目位于嵌套列表内,则函数 part? 返回 true。

但到目前为止,我只能让它与一阶列表中的信号项一起使用。 (还没有嵌套列表)

(define part?  
  (lambda (item l)
    (and (not (null? l))
         (or (= item (car l))
             (part? item (cdr l))))))

我的目标是拥有

一部分? (A (B)), (((B) A (B)) C) 是 #f 的

一部分? (AB), (C (AB) (C)) 的值是#t

我应该在哪里改进?如何使列表与嵌套列表进行比较?

My Goal is to make the function part? return true if a list or an item is inside the nested list.

But so far I can only get it working with signal item inside a first order list. (not nested list yet)

(define part?  
  (lambda (item l)
    (and (not (null? l))
         (or (= item (car l))
             (part? item (cdr l))))))

my goal is to have

part? of (A (B)), (((B) A (B)) C) is #f and

part? of (A B), (C (A B) (C)) is #t

Where I should improve on this? How can I make the list to compare with the nested list?

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

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

发布评论

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

评论(3

极致的悲 2024-08-12 07:51:25

免责声明:我已经 20 年没有定期写计划了。

我认为你想从整个 lispy/schemey 方法的角度来思考这个问题,即建立你的条件。

给定一个输入 item,您想要查找列表是否包含该项目。

  1. 如果列表不为空,则列表可以包含项目。

  2. 如果列表中的汽车与该项目匹配或者列表中的汽车包含该项目,则

  3. 如果列表的 cdr 包含项目,则列表包含项目。

  4. 要考虑的最后一个问题,(part? '(ab) '(ab)) 的结果是什么?

我会像这样编写代码,

(define part? (lambda (item l)
    (cond ((null? l) f)
          ((or (same? item (car l)) (part? item (car l))))
          (t (part? item (cdr l)))
    )
))

(define same? (lambda (a b) (eq? a b)))

我使用了 cond 结构,因为它非常适合此类问题 - 解决问题感觉是正确的 - 请注意空检查。我写的也一样吗?作为辅助函数,以防您想自己编写它。你也可以这样简单地实现它:

(define same? (lambda (a b)
    (cond ((and (atom? a) (atom? b)) (eq? a b))
          ((and (list? a) (list? b)) (and (same? (car a) (car b)) (same? (cdr a) (cdr b))))
          (f f)
    )
))

这基本上是说,如果两个项目都是原子并且它们是 eq ,或者它们都是列表并且汽车相同并且 cdrs 相同,则它们是相同的,否则为 false。

您可以轻松地重写相同的内容吗?这样

(define same? (lambda (a b) (equal? a b)))

做的要点是代码中存在一个瓶颈 - 如何确定两个项目是否相同。如果你将这个瓶颈分解成它自己的功能,你就可以用不同的机制来代替它。我知道你还没有到这里,但你将在某一时刻:你还可以重写代码,以便传入谓词。像这样的东西(以及更多最新的方案程序员,请随意纠正我):

(define part-pred? (lambda (same-pred item l)
    (cond ((null? l) f)
          ((or (same-pred item (car l)) (part? item (car l))))
          (t (part? item (cdr l)))
    )
))

(define part-eq? (lambda (item l) (part-pred? 'eq? item l)))
(define part-same? (lambda (item l) (part-pred? 'same? item l)))
(define part-equal? (lambda (item l) (part-equal? 'equal? item l)))

现在,这已将部分的概念抽象为应用部分结构规则和您提供的相等谓词的函数。这使得改变规则变得非常容易。当你使用mapcar时,这会更有意义。

DISCLAIMER: I haven't written scheme regularly in 20 years.

I think you want to think about this problem in terms of the whole lispy/schemey approach which is to establish your conditions.

Given an input, item, you want to find if a list contains that item.

  1. A list may contain an item if the list is not null.

  2. A list contains an item if the car of the list matches the item or if the car of the list contains the item

  3. A list contains an item if the cdr of the list contains the item.

  4. A final question to consider, what is the result of (part? '(a b) '(a b))?

I would write the code like this

(define part? (lambda (item l)
    (cond ((null? l) f)
          ((or (same? item (car l)) (part? item (car l))))
          (t (part? item (cdr l)))
    )
))

(define same? (lambda (a b) (eq? a b)))

I used the cond structure because it fits well with problems of this sort - it just feels right to break the problem out - notice the null check. I wrote same? as a helper function in case you want to write it yourself. You could just as easily to it this way:

(define same? (lambda (a b)
    (cond ((and (atom? a) (atom? b)) (eq? a b))
          ((and (list? a) (list? b)) (and (same? (car a) (car b)) (same? (cdr a) (cdr b))))
          (f f)
    )
))

which basically says that two items are the same if they are both atoms and they are eq or they are both lists and the cars are the same and the cdrs are the same, otherwise false.

You can just as easily rewrite same? as this:

(define same? (lambda (a b) (equal? a b)))

The point of doing that is that there is a bottleneck in the code - how to determine if two items are the same. If you break that bottleneck out into its own function, you can replace it with different mechanisms. I know you're not here yet, but you will be at one point: you will also be able to rewrite the code so that the predicate is passed in. Something like this (and more up-to-date scheme programmers, feel free to correct me):

(define part-pred? (lambda (same-pred item l)
    (cond ((null? l) f)
          ((or (same-pred item (car l)) (part? item (car l))))
          (t (part? item (cdr l)))
    )
))

(define part-eq? (lambda (item l) (part-pred? 'eq? item l)))
(define part-same? (lambda (item l) (part-pred? 'same? item l)))
(define part-equal? (lambda (item l) (part-equal? 'equal? item l)))

This has now abstracted the notion of part to be a function that applies the part structural rules and an equality predicate which is supplied by you. That makes it really easy to change the rules. This will make more sense when you hit mapcar.

偏爱你一生 2024-08-12 07:51:25

这里使用的 = 函数的问题是,它只为数字定义。要测试任意数据的相等性,可以使用谓词 eq?eqv?equal?。这里列出了从最有区别的(eq?,基本上类似于指针比较)到最没有区别的(equal?将考虑类型和结构)。 eqv? 谓词介于两者之间(对于数字来说是类型感知的,对于其他任何东西来说就像 eq? 一样)。

要比较列表,您通常会使用equal?

编辑有关这些谓词的详细信息可以在 R6RS

The problem with the = function used here is, that it is only defined for numbers. To test arbitrary data for equality, there are the predicates eq?, eqv?, and equal?. These are listed here from most discriminating (eq?, basically something like a pointer comparison) to least discriminating (equal? will consider type and structure). The eqv? predicate is somewhere in between (type-aware for numbers, otherwise like eq? for anything else).

To compare lists, you will usually use equal?.

Edit Details on these predicate can be found in the R6RS.

云归处 2024-08-12 07:51:25

您的解决方案缺少这个想法,因为您正在处理嵌套列表,您需要检查每个列表中的每个项目是否是一个列表本身,如果是,则检查给定列表是否是另一个列表的一部分或其余列表的一部分如果列表不是,那么您需要检查第一个项目是否相等,以及给定列表的其余部分是否是另一个列表的一部分。

(define part? item l
  (cond (and (list? (car item)) (not (list? (car l))) ...)
        (and (not (list? (car item))) (list? (car l)) ...)
        (and (not (list? (car item))) (not (list? (car l))) ...) 
        (and (list? (car item)) (list? (car l))) ...)

Your solution is missing the idea, since you're dealing with nested lists you need to check if each item in each list is a list itself, if it is then check if the given list is part of the other or part of the rest of the list if not then you need to check the first items are equal and if the rest of the given list is part of the other.

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