Вот заглушка с заявлением о цели, подписью и вашими тестами:
;; String String -> String
;; keeps all letters that occur in l, replaces with "_" otherwise
(check-expect (anti-omit "william" "li") "_illi__")
(check-expect (anti-omit "william" "l") "__ll___")
(define (anti-omit w l)
"")
Поскольку вы используете язык учащегося и, как вы указываете в заголовке вопроса, который хотите повторить в данных ... вам понадобится рекурсивное определение данных :
;; String is one of:
;; - ""
;; - (string-append 1String String)
Заполните определение этой функции:
;; String -> String
;; is str equal to "" ?
(define (string-empty? str)
...)
более строгое определение данных для двух других функций (которые соответствуют остальным и первым в списке):
;; NEString is one of:
;; - (string-append 1String "")
;; - (string-append 1String NEString)
Некоторые другие функции, которые вы должны выполнить:
;; NEString -> String
;; remove the first 1String from str
(define (string-rest str)
...)
;; NEString -> String
;; the first 1String form str
(define (string-first str)
...)
Теперь вы можете создавать такие функции в Strings:
;; [1String -> 1String] String -> String
;; Applies the function f on each 1String in s
(define (map-str f s)
(cond [(string-empty? s) ""]
[else (string-append (f (string-first s)) (map-str f (string-rest s)))]))
Аналогично, заполните это определение:
;; 1String String -> Boolean
;; is does 1String occur in String?
(define (member-str e l)
...)
Наш «список пожеланий» завершен, и мы можем составить наших помощников, чтобы завершить финальную функцию:
(define (anti-omit w l)
(map-str (λ (x) (if (member-str x l) x "_")) w))
Аналогичная версия, которая использует взрыв и развертывание и не нуждается ни в одной из функций, которые мы определили (используйте это как эталонную реализацию):
(define (anti-omit-ref w l)
(implode (map (λ (x) (if (member? x (explode l)) x "_")) (explode w))))