如何计算Scheme中一个列表中的模式出现在另一个列表中的次数

如何计算Scheme中一个列表中的模式出现在另一个列表中的次数,scheme,racket,mit-scheme,Scheme,Racket,Mit Scheme,我在一个计划项目中呆了大约5个小时。我正在编写的程序应该将两个列表作为输入,然后计算第一个列表中的模式出现在第二个列表中的次数 例如:>patt'bc'abcdebc==>answer=2 点击“a b c”a b c a b c d e a b c c==>答案=3 点击a b c a b c d e b c==>答案=1 下面是我到目前为止的代码 (define (patt lis1 lis2) (cond ((null? lis1) 0) ((null? lis2) 0

我在一个计划项目中呆了大约5个小时。我正在编写的程序应该将两个列表作为输入,然后计算第一个列表中的模式出现在第二个列表中的次数

例如:>patt'bc'abcdebc==>answer=2

点击“a b c”a b c a b c d e a b c c==>答案=3

点击a b c 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)))
    ))

有人能帮我解决这个问题吗。谢谢

如果一个列表以另一个列表开始,请考虑测试的子问题

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

如果希望出现不重叠的引用,可以使用前缀匹配,返回列表的后缀,以便跳过匹配的部分


也使用equals?为了结构平等,而不是情商?这表示标识。

如果一个列表以另一个列表开头,请考虑测试的子问题

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

如果希望出现不重叠的引用,可以使用前缀匹配,返回列表的后缀,以便跳过匹配的部分


也使用equals?为了结构平等,而不是情商?用于标识。

您需要将问题分为几个部分:

(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)
  ...)
因此,您可以想象搜索模式计数出现“a”a。当从第一个元素中找到它时,需要在下一个元素中再次搜索。因此,a的结果是3,因为匹配重叠。每个子列表(空列表除外)都涉及使用前缀


祝你好运

您需要将问题分成几个部分:

(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)
  ...)
(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))))
因此,您可以想象搜索模式计数出现“a”a。当从第一个元素中找到它时,需要在下一个元素中再次搜索。因此,a的结果是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))))
(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

在给这个家庭作业问题一点时间来思考之后,我不认为张贴额外的答案有什么害处-

(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

计算长度似乎不必要这是递归循环结束条件,请检查递归循环列表的长度是否小于模式长度,如果是,则不再需要循环,结束循环。对,但长度是一个昂贵的计算;它遍历整个列表。计算长度似乎不必要。这是一个递归循环结束条件,请检查递归循环列表的长度是否小于模式长度,如果是,则不再需要循环,结束循环。对,但长度是一个昂贵的计算;它遍历整个列表。