How to compute the number of times pattern in one list appears in other list in Scheme

北慕城南 提交于 2019-11-29 16:44:31

Consider the subproblem of testing if a list starts with another list.

Then do this for every suffix of the list. Sum up the count of matches.

If you want non overlapping occurrences, you can have the prefix match, return the suffix of the list so that you can skip over the matching part.

Also use equals? for structural equality, not eq? which is for identity.

You need to divide the problem into parts:

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

So with this you can imagine searching for the pattern (count-occurences '(a a) '(a a a a)). When it is found from the first element you need to search again on the next. Thus so that the result is 3 for the (a a a a) since the matches overlap. Every sublist except when it's the empty list involves using prefix?

Good luck!

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

After giving this homework problem a little time to marinate, I don't see the harm in posting additional answers -

(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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!