球拍:计算兄弟姐妹的数量

时间:2015-03-10 20:53:20

标签: list tree nested racket siblings

将嵌套列表作为输入,我试图找到如何输出元素的'兄弟姐妹'的数量。就树而言,有多少其他叶节点属于同一父/根节点。

我的代码提供了错误的输出(这是一个非常糟糕的代码),我不确定如何完全接近问题

(define (siblings lst n)
 (cond
     [(empty? lst) false]
     [(member? n lst) (sub1 (length lst))]
     [else (siblings (rest lst) n)]))

样本结果:如果给出(列表(列表2 1)3(列表4))和3,则产生0

(列表(列表1 2 3)(列表(列表4 5 6)))和5 - > 2

1 个答案:

答案 0 :(得分:0)

您的代码必须做两件事:

  1. 找到包含 n
  2. 的分支
  3. 计算该分支中兄弟姐妹的数量,考虑其他分支机构从那里开始的可能性。
  4. 找到包含 n 的分支,假设 n 只能出现一次:

    (define (find-branch root n)
      (cond ((empty? root) empty)
            ((memq n root)
              root)
            ((list? (first root))
             (let ((subresult (find-branch (first root) n)))
               (if (not (empty? subresult))
                   subresult
                   (find-branch (rest root) n))))
            (else (find-branch (rest root) n))))
    

    因为您正在使用"初学者,"将所有工具从工具箱中取出。幸运的是,它仍然有number?,因此,如果可以安全地假设此分配中的任何数字都不是列表,则可以像这样定义list?

    (define (list? n) (not (number? n)))
    

    将您的示例树作为输入,它将返回:

    (4 5 6)
    

    以上示例在memq上不必要地使用rest 输入列表作为使用递归迭代相同列表的结果。

    以上是上述版本的更高效版本,但您无法在Beginning Student中实现它:

    (define (find-branch root n)
      (cond ((empty? root) false)
            ((memq n root) root)
            (else (foldl (λ (a b)
                            (if (empty? a) b a))
                         empty
                         (map (λ (sublist)
                                 (find-branch sublist n))
                           (filter list? root))))))
    

    您将结果传递给函数以计算兄弟姐妹。我之前提供的版本可以在真正的Racket中使用,但不是教师使用的Beginning Student版本:

    (define (count-siblings root mem)
      (count (λ (sib)
                (and (not (eq? sib mem))
                     (not (list? sib)))) root))
    

    这是一个与初学者兼容的版本:

    (define (count-siblings lst n counter)
      (cond
         [(empty? lst) counter]
         [(and (not (list? (first lst)))
               (not (eq? n (first lst)))) 
          (count-siblings (rest lst) n (add1 counter))]
         [else (count-siblings (rest lst) n counter)]))
    

    最后,把两者放在一起:

    (define (find/count-siblings root n)
       (count-siblings (find-branch root n) n 0))