Строки немного раздражают в работе, поэтому мы обертываем их вокруг рабочей функции, которая вместо этого работает со списками.Таким образом, мы можем избежать повсюду возиться с преобразованиями.
(define (remove-repeats str)
(list->string (remove-repeats/list (string->list str))))
Теперь мы можем определить функцию удаления-повторов / списка, используя простую рекурсию:
(define (remove-repeats/list xs)
(cond
[(empty? xs) xs]
[(empty? (cdr xs)) xs]
[(equal? (car xs) (cadr xs)) (remove-repeats/list (cdr xs))]
[else (cons (car xs) (remove-repeats/list (cdr xs)))]))
Это не хвост-рекурсивный, но теперь проще добавить аккумулятор:
(define (remove-repeats str)
(list->string (remove-repeats/list-acc (string->list str) '())))
(define (remove-repeats/list-acc xs acc)
(cond
[(empty? xs) (reverse acc)]
[(empty? (cdr xs)) (reverse (cons (car xs) acc))]
[(equal? (car xs) (cadr xs)) (remove-repeats/list-acc (cdr xs) acc)]
[else (remove-repeats/list-acc (cdr xs) (cons (car xs) acc))]))