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

人走茶凉 提交于 2019-11-28 10:59:42

问题


I am stuck up in a Scheme program for about 5 hours. The program that I am working on should take two lists as input and then compute the number of times the pattern within the first list appears on the second list.

For example : > (patt '(b c) '(a b c d e b c)) ==> answer = 2

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

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

Below is the code that I have till now.

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

Can someone please help me solve this. Thanks!


回答1:


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.




回答2:


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!




回答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))))



回答4:


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


来源:https://stackoverflow.com/questions/54758619/how-to-compute-the-number-of-times-pattern-in-one-list-appears-in-other-list-in

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