Racket (Рекурсивные структуры и шаблоны обработки)
Я в тупике при обработке этой структуры, я хочу написать функцию, которая сообщает, сколько тем возникает в обсуждении.
; a Discussion is (make-discussion String Digressions)
(define-struct discussion [topic digressions])
; Digressions is [ListOf Discussion]
; count-topics : Discussion -> Number
; counts the number of total topics in a discussion, including repeated topics
(define (count-topics d)
(cond
[(empty? (discussion-digressions d)) 0]
[(cons? (discussion-digressions d)) (add1 (count-topics (make-discussion (first (discussion-topic d))
(list (make-discussion (rest (discussion-digressions d)))))))]))
(check-expect (count-topics (make-discussion "music" (list (make-discussion "politics" empty)))) 2)
Я пытался несколько часов и еще не решил. Я не уверен, что делать дальше, у кого-нибудь есть острый глаз на Racket? Я попытался сначала обработать тему, но мне так и не удалось.
1 ответ
Вы не должны использовать make-discussion
в вашем решении мы пытаемся обходить структуры, а не создавать новые. Следует рассмотреть два случая:
- Если
digressions
список пуст, значит, мы нашли одну тему, и больше некуда идти. - В противном случае мы считаем одну тему (текущую) и вызываем рекурсию по всем элементам в списке
digressions
, добавляя свои результаты. Это легко реализовать, используяapply
а такжеmap
Это то, что я имею в виду:
(define (count-topics d)
(cond
[(empty? (discussion-digressions d)) 1]
[else (add1 (apply + (map count-topics (discussion-digressions d))))]))
Конечно, вы можете решить эту проблему, не используя apply
а также map
, но для этого лучше писать отдельные процедуры, как предлагает Алекс. Во всяком случае, мой подход работает так, как ожидалось:
(count-topics
(make-discussion "music"
(list (make-discussion "politics" empty))))
=> 2