【问题标题】:How to compute the number of times pattern in one list appears in other list in Scheme如何计算一个列表中的模式出现在Scheme中的另一个列表中的次数
【发布时间】:2019-02-19 03:51:21
【问题描述】:

我在一个 Scheme 程序中被困了大约 5 个小时。我正在处理的程序应该将两个列表作为输入,然后计算第一个列表中的模式出现在第二个列表中的次数。

例如:> (patt '(b c) '(a b c d e b c)) ==> 答案 = 2

(patt '(a b c) '(a b c a b c d e a b c c c)) ==> 答案 = 3

(patt '((a b) c) '(a b (a b) c d e b c)) ==> 答案 = 1

下面是我到现在为止的代码。

(define (patt lis1 lis2)
  (cond
    ((null? lis1) 0)
    ((null? lis2) 0)
    [(and (> (length lis1) 1) (eq? (car lis1) (car lis2))) (patt (cdr lis1) (cdr lis2))]
    ((eq? (car lis1) (car lis2)) (+ 1 (patt lis1 (cdr lis2))))
    (else (patt lis1 (cdr lis2)))
    ))

谁能帮我解决这个问题。谢谢!

【问题讨论】:

    标签: scheme racket mit-scheme


    【解决方案1】:

    考虑测试一个列表是否以另一个列表开头的子问题。

    然后对列表的每个后缀执行此操作。总结匹配数。

    如果你想要不重叠的出现,你可以让前缀匹配,返回列表的后缀,这样你就可以跳过匹配的部分。

    还可以使用 equals? 来表示结构相等,而不是使用 eq? 来表示身份。

    【讨论】:

      【解决方案2】:

      你需要把问题分成几部分:

      (define (prefix? needle haystack)
        ...)
      
      (prefix? '() '(a b c))        ; ==> #t
      (prefix? '(a) '(a b c))       ; ==> #t
      (prefix? '(a b c) '(a b c))   ; ==> #t
      (prefix? '(a b c d) '(a b c)) ; ==> #f
      (prefix? '(b) '(a b c))       ; ==> #t
      
      (define (count-occurences needle haystack)
        ...)
      

      因此,您可以想象搜索模式(count-occurences '(a a) '(a a a a))。当从第一个元素中找到它时,您需要在下一个元素上再次搜索。因此,由于匹配重叠,(a a a a) 的结果是 3。除空列表外,每个子列表都涉及使用prefix?

      祝你好运!

      【讨论】:

        【解决方案3】:
        (define (patt list1 list2)
          (let ([patt_length (length list1)])
            (let loop ([loop_list list2]
                       [sum 0])
              (if (>= (length loop_list) patt_length)
                  (if (equal? list1 (take loop_list patt_length))
                      (loop (cdr loop_list) (add1 sum))
                      (loop (cdr loop_list) sum))
                  sum))))
        

        【讨论】:

        • 计算length似乎没有必要
        • 是递归循环结束条件,检查递归loop_list的长度是否小于pattern长度,如果是则不需要循环,结束循环。
        • 对,但是length 是一个昂贵的计算;它遍历整个列表。
        【解决方案4】:

        在给这个作业问题一点时间来腌制之后,我认为发布其他答案没有什么害处 -

        (define (count pat xs)
          (cond ((empty? xs)
                 0)
                ((match pat xs)
                 (+ 1 (count pat (cdr xs))))
                (else
                 (count pat (cdr xs)))))
        
        (define (match pat xs)
          (cond ((empty? pat)
                 #t)
                ((empty? xs)
                 #f)
                ((and (list? pat)
                      (list? xs))
                 (and (match (car pat) (car xs))
                      (match (cdr pat) (cdr xs))))
                (else
                 (eq? pat xs))))
        
        (count '(a b c) '(a b c a b c d e a b c c c)) ;; 3
        
        (count '((a b) c) '(a b (a b) c d e b c)) ;; 1
        
        (count '(a a) '(a a a a)) ;; 3
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-10
          • 2020-05-14
          相关资源
          最近更新 更多